views:

528

answers:

4

The customer wants us to "log" the "actions" that a user performs on our system: creation, deletion and update, mostly. I already have an aspect that logs the trace, but that works at a pretty low level logging every method call. So if a user clicked on the button "open medical file" the log would read:

  1. closePreviousFiles("patient zero")
  2. createMedicalFile("patient zero") --> file #001
  3. changeStatus("#001") --> open

while the desired result is:

  1. opened medical file #001 for patient zero

I'm thinking of instrumenting the Struts2 actions with log statements, but I'm wondering... is there another way to do that? I might use AspectJ again (or a filter) and keep the logic in just one place, so that I might configure the log easily, but then I'm afraid everything will become harder to understand (i.e. "the log for this action is wrong... where the heck should I look for the trouble?").

+1  A: 

I recently post-processed logs to generate summary. You may want to consider that approach, especially if #2 and #3 in the above logs are generated at different places and the desired result would require to carry around state from one place to another.

Hemal Pandya
one of my main worries, in fact, is that keeping the logging logic in one place would require passing the session and any given set of parameters... post processing is an interesting option indeed!
Manrico Corazzi
Glad I could be useful. I was a little hesitant to write, knowing very little or nothing about Struts and AspectJ :-)
Hemal Pandya
+1  A: 

If you are working with medical data you may want to consider both logging and versioning. I would even think about doing this with database triggers. I don't do a lot of Java programming, but I've discussed this very issue with our Student Information System team. They use Oracle on the backend and register a session variable with their connections. Their triggers use this session variable to create log entries and version histories (on updates/deletes) of critical tables. This gives them both auditing and rollback capabilities. I would think that both of these would be useful for a medical records application.

They also use log4j to do application level logging, but the data logging takes place in the database.

tvanfosson
I already do log versions of medical data, with a versatile class which saves "differences" between many different records; this is done through custom sparse code. Nonetheless our customers would like to log other data (i.e. administrative operations such as user/groups creations and update).
Manrico Corazzi
+1  A: 

Sounds like your client wants an audit trail of the user's actions in the system.

Consider that at each action's entry point (from the web request) to start an audit entry with an enum/constant on the action. Populate it with information user has provided if possible.

At exit/finally, indicate in the audit if it is successful or failed. An example in pseudocode:

enum Actions {
  OPEN_MEDICAL_FILE
  ...
}

void handleRequest(...) {
  String patient = ...;
  Audit audit = new Audit(OPEN_MEDICAL_FILE);
  audit.addParameter("patient", patient);
  try {
     ... more things ..
     audit.addParameter("file", "#001");
     ... more things ...
     audit.setSuccess();
  } finally {
    audit.save();
  }
}

What is important here is that all user actions are saved, regardless of success or failure. Also, the client really really need to know all relevant information along with the action.

Since we are logging action constants and data, the presentation of the audit to the client can be seperately coded. You gain flexibility too, since a change of presentation string (eg. "opened medical file #001 for patient zero" to "patient zero #001 medical file opened) is not determined at the time of the action, but later. You don't have to remassage the audit data.

Kent Lai
+1  A: 

I've done similar stuff in Struts2 actions, I used "log4j". Depending on your Application Server, it might have an integrated logging system allowing the use of message catalogs (e.g.: Weblogic).

xgMz