'Logging configuration with file appenders and stdout in grails

I have a configuration error in my grails application that's causing my appenders to send output to the wrong place, or not at all. There seem to be a number of questions regarding duplicate logging but I have been unable to apply any of the answers to my situation.

Here is my logging config snippet:

log4j = {

        appenders {
                // appender for usage tracking
                appender new org.apache.log4j.RollingFileAppender(
                        name:"usageAppender",
                        maxFileSize:"1000KB",
                        maxBackupIndex: 10000,
                        file: "/var/log/tomcat6/app/usage.log",
                        layout:pattern(conversionPattern: '%d{DATE} %5p %c{1}:%L - %m%n')
                )
                appender new org.apache.log4j.RollingFileAppender(
                        name:"application",
                        maxFileSize:"1000KB",
                        maxBackupIndex: 10000,
                        file:"/var/log/tomcat6/app/application.log",
                        layout:pattern(conversionPattern: '%d{DATE} %8X{memoryused} %5p %t %c{1}:%L %X{username} %X{request} - %m%n')
                )
                console name:'stdout', layout:pattern(conversionPattern: '%d{DATE} %8X{memoryused} %5p %t %c{1}:%L %X{username} %X{request} - %m%n')
        }
        root {
                // also tried error 'stdout'
                error  'application'
        }

        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'

        info 'usageAppender':'usage.gui'
}

When my program runs, output appears in catalina.out, in usage.log and in application.log. Output sent directly to stdout (bypassing log4j) appears in catalina.out

If I set

 info additivity: false 'usageAppender': 'usage.gui'

Then nothing is logged to either file appender, but stdout still goes into catalina.out (bypassing log4j).

I would like the output from the 'usage.gui' logger to go to the usage.log file, output from all other logging to go to the application.log file, and all print statement output to go to catalina.out. I don't want redundant logging. How do I configure this?

UPDATE In answer to @dmahapatro's question, logging in the application is done either with standard grails logging

log.trace('some event');

or with a custom logger created like this:

def usageLog
public UsageService() {
    usageLog = Logger.getLogger("usage.gui")
}

and used by calling this function:

protected void writeRecord(String topicId, String user, Long id, Long priorId, Long clientTime, String component, String action, String otherData) {
    String msg = "$topicId\t$user\t$id\t$priorId\t$clientTime\t$component\t$action\t$otherData"
    usageLog.info(msg)
}


Solution 1:[1]

Try this setting.

  • Keep stdout at root (if needed change the level to info/debug/all). Set additivity to false in order to restrict console logs getting added to usage or application appender.
  • Other appenders inherit from root, set additivity false for application and usage to restrict console logging.
  • Use grails.app against application to log all application related logs in application.log.

Like:

root {
         error 'stdout'
         additivity: false
     }

info usageAppender: 'usage.gui'
        additivity: false

info application: 'grails.app'
       additivity: false

Note:-
Logs at the different logging level will not work for same package structure. For example:

info usageAppender: 'usage.gui'
error usageAppender1: 'usage.gui'

will only log error for usage.gui.

Solution 2:[2]

Most of the time you don't see the log printing from src/groovy because some where else the higher Level ERROR set in the application. So if you set all the classes log to debug level then the logger debug is working.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 srinivasa dutt pulipaka