Search code examples
grailsgroovylog4jconfig

Grails Log4J Can't Configure Info Logger without Using Root


So I think I have a pretty simple problem with configuring log4j in grails, but can't find a solution anywhere. I'm currently trying to have it set up where all errors go to a stacktrace file, then all info + warning logs that the app prints out go to the console. This is how I currently have it configured:

log4j = {

appenders {
    rollingFile name: "stacktrace", maxFileSize: "10MB", maxBackupIndex:2, file:"/tmp/logs/stacktrace.log", threshold: org.apache.log4j.Level.ERROR
    console name: "stdout", threshold: org.apache.log4j.Level.INFO
}

root {
    error 'stacktrace', 'stdout'
}

info stdout: 'grails.app'

error   'org.codehaus.groovy.grails.web.servlet',        // controllers
        'org.codehaus.groovy.grails.web.pages',          // GSP
        'org.codehaus.groovy.grails.web.sitemesh',       // layouts
        'org.codehaus.groovy.grails.web.mapping.filter', // URL mapping
        'org.codehaus.groovy.grails.web.mapping',        // URL mapping
        'org.codehaus.groovy.grails.commons',            // core / classloading
        'org.codehaus.groovy.grails.plugins',            // plugins
        'org.codehaus.groovy.grails.orm.hibernate',      // hibernate integration
        'org.springframework',
        'org.hibernate',
        'net.sf.ehcache.hibernate'

}

Right now, I have to have the root set up for it to print the errors to the file. But if I try to add the Info/Warn level to the root configuration to go to stdout it logs everything that's not specifically defined, so info/warning logs from plugins and stuff come through when I just want the ones from the grails app. Is there a way I can point different log levels to different appenders without needing to set it up through the root?


Solution

  • Is there a way I can point different log levels to different appenders without needing to set it up through the root?

    Yes. Log4j provides a good bit of flexibility around that. For example, you can attach appenders to specific loggers by passing the name as a key to one of the log level methods:

    error myAppender: "grails.app.controllers.BookController"
    

    To add more than one appender to the logger, add them to the same level declaration:

    error myAppender:      "grails.app.controllers.BookController",
          myFileAppender:  ["grails.app.controllers.BookController",
                            "grails.app.services.BookService"],
          rollingFile:     "grails.app.controllers.BookController"
    

    We have documented a lot of relevant capabilities at https://grails.github.io/grails2-doc/2.5.6/guide/conf.html#logging.