Grails - Grails Audit Logging Plugin...

The Audit Logging plugin can add Hibernate Events based Audit Logging to a Grails project and it can also add support to domain models for hooking into the hibernate events system. Support for the following closures are added: onSave, onDelete, and onChange. The onChange closure can be used in two ways. First it can be used with no parameters or it can be used with two parameters, oldMap and newMap. The first parameter is a LinkedHashMap representing the old state of the object before the change was applied, the second parameter is a LinkedHashMap representing the state of the object after changes are applied.

NOTE: GORM Events hooks into the ''beforeInsert'' and the ''beforeUpdate'' events which work great for preventing updates but do not work well for ''Audit Logging'' where we would need critical information about the entity that is only available after these actions complete. I have chosen to prefix the handler names with "on" so that they do not conflict with other handler names in other existing plugins.

Installation

$ grails install-plugin audit-logging

Usage

You can use the grails-audit-logging plugin in several ways. First, in a domain class…

static auditable = true
enables audit logging using the introduced domain class AuditLogEvent which will record insert, update, and delete events. Update events will be logged in detail with the property name and the old and new values. Additionally you may use the optional event handlers.

Examples:

class Person {

static auditable = true Long id Long version

String firstName String middleName String lastName

String email

static constraints = { firstName(nullable:true,size:0..60) middleName(nullable:true,size:0..60) lastName(nullable:false,size:1..60) email(email:true) }

def onSave = { println "new person inserted" // may optionally refer to newState map } def onDelete = { println "person was deleted" // may optionally refer to oldState map } def onChange = { oldMap,newMap -> println "Person was changed ..." oldMap.each({ key, oldVal -> if(oldVal != newMap[key]) { println " * $key changed from $oldVal to " + newMap[key] } }) }//*/ }

Alternately you may choose to disable the audit logging and only use the event handlers. You would do this by specifying:
static auditable = [handlersOnly:true]
… with handlersOnly:true specified no AuditLogEvents will be persisted to the database and only the event handlers will be called.

As of version 0.3 additional configuration can be specified in the Config.groovy file of the project to help log the authenticated user for various security systems. For many security systems the defaults will work fine. To specify a property of the userPrincipal to be logged as the actor name (the person performing the action which triggered the event) in Config.groovy add these lines:

auditLog {
  actor = 'userPrincipal.name'
}
...or alternately…
auditLog {
  actor = 'userPrincipal.id'
}
… if you prefer to log the user's id.

If you are using a custom authentication system in your controller that puts the user data into the session you can set up the actor to work with this data instead...

In Config.groovy

auditLog {
  actor = 'session.username'
}
… or if your user is similar to the simple authentication user object in the tutorials...

in Config.groovy

auditLog {
  actor = 'session.user.name'
}
… finally if you are using a system such as CAS you can specify the CAS user attribute using a special configuration property to get the CAS user name. In Config.groovy just add the following lines to the top of the file:
import edu.yale.its.tp.cas.client.filter.CASFilter
auditLog {
  username = CASFilter.CAS_FILTER_USER
}
… and the audit_log table will have a record of which user and what controller triggered the hibernate event.