Grails: How to log within static methods

Posted on August 20th, 2008 by Reiner.
Categories: Grails, English.

Grails injects a log object for each artifact, but these loggers are not accessible within static methods.

Here’s a quick-and-dirty code snippet sample that demonstrates how to log from a static method within domain class Account. The trick is to get the Logger by invoking org.apache.commons.logging.LogFactory.getLog(this):

import org.apache.commons.logging.LogFactory

static Account createOrFindByImei(String imei)
{
    Account result = Account.findByImei(imei)
    return result ? result  :
    saved(new Account(
            imei:imei,
            email:Login.getCurrentLogin().email,
            name:"* New Account ($imei) created at " + new Date()))
}

private static Account saved(Account account)
{
    if(account.save())
    {
        return account
    }
    LogFactory.getLog(this)
      .error("!saved: $account.errors", new Throwable("*STACKTRACE*"))
}

4 comments.

Burt

Comment on August 20th, 2008.

Yuck. For one, Grails uses Log4j so there’s no need to bring in Commons Logging just because you can. And specifying the logger category this way is very brittle and susceptible to copy/paste problems where you forget to change the string - how about this instead: Logger.getLogger(this).error(”!saved: $account.errors”) - “this” in a static Groovy method refers to the current class.

Shawn Hartsock

Comment on August 20th, 2008.

@Burt …

Logger.getLogger(this).error(”!saved: $account.errors”)

Thanks Burt, that’s much cleaner. That should be in the tutorial pages on the main site or in one of the docs. Some of us have a hard time getting groovier with our code.

Reiner

Comment on August 21st, 2008.

Thanks Burt,

for the “this” within static methods, and the $account too.

For the Commons Logging, I believe it’s already there. The “log” objects injected into each and every Grails artifact are indeed implementations of org.apache.commons.logging.Log. At least according to Using Logging in Graeme’s The Definite Guide to Grails, page 143f. Commons logging serves as an abstraction layer which in turn delegates to other logging frameworks (e.g. Log4j). Why should I bypass documented interfaces just because I can :-)

Burt

Comment on August 21st, 2008.

You’re right, it is a Commons Logger instance. But Grails is tightly coupled with Log4j, so I avoid using clogging since it’s an unnecessary wrapper that removes functionality. BTW - be careful of relying on DGG - it’s becoming quite dated and is no longer definitive :)

Leave a comment

Comments can contain some xhtml. Names and emails are required (emails aren't displayed), url's are optional.