January 18, 2010

Grails Goodness: Logging Service Method Calls with Dynamic Groovy

Because Grails is a Groovy web application framework we can use all the nice features of Groovy, like dynamic programming. Suppose we want to log all method invocation of Grails services. We have to look up the Grails services and override the invokeMethod() for the classes. Here we invoke the original method, but also add logging code so we can log when we enter and exit the method.

The best place to put our code is in grails-app/conf/BootStrap.groovy of our Grails application. Here we use the init closure to first look up the Grails service classes. Next we override the invokeMethod().

// File: grails-app/conf/BootStrap.groovy
class BootStrap {
    def grailsApplication

    def init = { ctx ->
    def destroy = { }
    private def setupServiceLogging() {
        grailsApplication.serviceClasses.each { serviceClass ->
            serviceClass.metaClass.invokeMethod = { name, args ->
                delegate.log.info "> Invoke $name in ${delegate.class.name}"
                def metaMethod = delegate.metaClass.getMetaMethod(name, args)
                try {
                    def result = metaMethod.invoke(delegate, args)
                    delegate.log.info "< Completed $name with result '$result'"
                    return result
                } catch (e) {
                    delegate.log.error "< Exception occurred in $name"
                    delegate.log.error "< Exception message: ${e.message}"
                    throw e