Grails Audit Logging Plugin
4% of Grails users
Dependency :
compile ":audit-logging:0.5.4"
Summary
Installation
$ grails install-plugin audit-logging
static auditable = true
Description
Adds conventions so that when you putin a domain class, any changes to the class are automatically logged for you.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.
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. If you'd like to get values logged on insert and delete events, add following in Config.groovy:
Additionally you may use the optional event handlers.Examples:
Alternately you may choose to disable the audit logging and only use the event handlers. You would do this by specifying:
… with handlersOnly:true specified no AuditLogEvents will be persisted to the database and only the event handlers will be called.
… if you prefer to log the user's username property.as there are some issues using Spring Security Core 1.1.2 Plugin:
if You save data from an unprotected URL (configAttribute:IS_AUTHENTICATED_ANONYMOUSLY) the principal is a String-object not a Principal-object.
to cope with this behaviour you should change above code to
don't forget to add
If you are using a custom authentication system in your controller that puts the user data into the session you can set up the actorClosure to work with your security system instead.
… and the audit_log table will have a record of which user and what controller triggered the hibernate event.… if instead you really want to trigger on version and lastUpdated changes you may specify an empty ignore list … like so …
You are only likely to want to change the defaults if you are working with a transactional database in test and production.
static auditable = true
Compatibility issues
Users of Grails 1.2.x and below should use version 0.5.3 of this plugin. Users of Grails 1.3.x and above should use version 0.5.4 (or greater) of this plugin.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
auditLog.verbose = trueclass 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]
}
})
}//*/
}static auditable = [handlersOnly:true]
Auditing Current User Information
As of version 0.5 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 {
actorClosure = { request, session ->
session.user?.username
}
}Spring Security Core 1.0.1 Plugin
Based off of Jorge Aguilera's example, the Spring Security Plugin uses the springSecurityService.auditLog {
actorClosure = { request, session ->
request.applicationContext.springSecurityService.principal?.username
}
}auditLog {
actorClosure = { request, session ->
if (request.applicationContext.springSecurityService.principal instanceof java.lang.String){
return request.applicationContext.springSecurityService.principal
}
def username = request.applicationContext.springSecurityService.principal?.username
if (SpringSecurityUtils.isSwitched()){
username = SpringSecurityUtils.switchedUserOriginalUsername+" AS "+username
}
return username
}
}import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtilsAcegi Plugin
Thanks to Jorge Aguilera for his example on how to integrate with the Acegi plugin:auditLog {
actorClosure = { request, session ->
return request.applicationContext.authenticateService.principal()?.username
}
}CAS Authentication
For example 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 {
actorClosure = { request, session ->
session?.getAttribute(CASFilter.CAS_FILTER_USER)
}
}Shiro Plugin
With Shiro, add the following lines to use the currently logged in user's username:auditLog {
actorClosure = { request, session ->
org.apache.shiro.SecurityUtils.getSubject()?.getPrincipal()
}
}Ignore List
It's possible to configure which properties get ignored for auditing.The default ignore field list is: 'version','lastUpdated' (+) if you want to provide your own ignore list do so by specifying the ignore list like so:static auditable = [ignore:['version','lastUpdated','myField']]static auditable = [ignore:[]]Transactional AuditLog events
In Config.groovy you may specify whether the Audit Log uses transactions or not. If set to true then the logger will begin and commit transactions around audit log save events. If set to false then the AuditLog will be persisted without a transaction wrapping its call to save. This setting should not be changed from defaults lightly as it can cause problems in integration testing.auditLog {
transactional = true
}