LAMS has a single audit log JBOSS_HOME/server/default/log/audit<date>.log, stored in .
Certain significant updates are recorded in this log. For example:
- New user is added to LAMS - the user's user id and login id are logged.
- A user modifies their password - the user's login is logged (but not the password!).
- Staff member editing a learner's entry in the monitoring screen - the old and new entries are logged.
- Staff member hiding or showing a learner's entry in the monitoring screen - the hidden entry is logged.
All tools must log editing/hiding/showing entries. If you are in any doubt as to whether something should be logged or not, then check with Ernie or Fiona.
The log is created using Log4J. It is configured to write out all information level entries (and above) that are generated from the org.lamsfoundation.lams.util.audit package. It uses a DailyRollingFileAppender, with the file rolling over at midnight.
It is implemented in org.lamsfoundation.lams.util.audit.AuditService, with the interface defined as IAuditService. It is found in lams.jar. This service is made available as the Spring bean "auditService". The audit service makes use of some internationalisation strings (are also stored in lams.jar).
The user creating the entry is recorded automatically - the audit service gets the current user from the shared session object. If the shared session object is missing then the log entry is still created.
Both the user id and the login name are recorded even though the data is redundant. This file will be scanned by a human from time to time, so it will be easier for them to recognise people by their login name. However login names change and user ids do not, so we also record the user id so we can track changes for a user even if the login name changes.
There will be one file for each day that there is an entry. The files should never overwrite themselves so it may become necessary to move older audit files to another disk as part of the general system administration.
Audit Log Interface and Creating a Log Entry
There are four calls available to create an audit log entry:
- public void log(String moduleName, String message): Generic call to log a message.
- public void logChange(String moduleName, Long originalUserId, String originalUserLogin, String originalText, String newText): Log a change to a piece of data. Designed to be used by tools when a staff member edits a learner's entry.
- public void logHideEntry(String moduleName, Long originalUserId, String originalUserLogin, String hiddenItem): Log the details about an item that has been hidden. Designed to be used by tools when a staff member hides a learner's entry.
- public void logShowEntry(String moduleName, Long originalUserId, String originalUserLogin, String hiddenItem): Log the details about an item that has been hidden. Designed to be used by tools when a staff member hides a learner's entry.
In general, if an event occurs in only one module (such as creating a user, changing user passwords), then the module should create its own message and call log(String moduleName, String message).
If the even occurs in many modules, such as hiding an item, then we write a helper method in the AuditService. This ensures consistency in the message across modules.
All messages in the audit log should be internationalised.
The moduleName should be a unique indicator of your module. For a tool, the tool signature is a good choice. For the core modules, it will be the name of the module - "learning", "monitoring", "admin", etc.
To call the auditService, your module should include the audit service as a property in your module's main service bean. Then it is just a matter of calling auditService.log(), auditService.logChange(), auditService.logHideEntry() or auditService.logShowEntry(). If you are calling object.toString() to generate the string the hiddenItem, don't forget to check that the object has a useful toString() method. Just writing out the object's memory address or object id isn't a lot of help.
For example, in the share resources tool: