Adding Logging Around All of the Methods of a Class With Groovy

| Comments

An interesting question came up on stack overflow, “In Groovy Is there a way to decorate every class to add tracing”. I came up with the following solution using groovy’s invokeMethod.

The invokeMethod method gets called by groovy’s MOP for every method call that happens on an object. If we add our own version, we need to make sure we keep a reference to the original metaClass so that within our invokeMethod, we can still get access to the other methods that we want to delegate to.

class Foo {
    def bar() {
        println "in bar"
    def baz(String name) {
        println "in baz with $name"

def decorateMethodsWithLogging(clazz) {
    def mc = clazz.metaClass
    mc.invokeMethod = { String name, args ->
        println "before $name, args = $args"
        def result = mc.getMetaMethod(name, args).invoke(delegate, args)
        println "after $name"
        return result


def f = new Foo()


before bar, args = []
in bar
after bar
before baz, args = [qux]
in baz with qux
after baz