English 中文(简体)
Grails log4j configuration
原标题:
  • 时间:2009-11-19 18:23:53
  •  标签:
  • grails
  • log4j

I ve repeatedly had problems with the DSL introduced by Grails in version 1.1 for configuring Log4J. My current configuration looks like this:

log4j = {        
    debug  com.mypackages 

    appenders {
        console name:  stdout , layout: pattern(conversionPattern:  %d{dd-MM-yyyy HH:mm:ss,SSS} %5p %c{1} - %m%n )
        rollingFile name:  hibeFile , file: "hibeFile", maxFileSize:  500KB 
    }

    // By default, messages are logged at the error level to both the console and hibeFile
    root {
        error  stdout ,  hibeFile 
        additivity = true
    }
}

The intention here is:

  • Log com.mypackages at the debug level and all others at the error level
  • Log all output to a file named hibeFile and the console

This works fine when I run the application or the integration tests. However, when I run the unit tests no logging appears either in the console, or in the "System.out" or "System.err" links shown in the Grails test report. How can I see my logs when running unit tests?

Thanks, Don

问题回答

AFAIK, when running a Grails unit test, the whole logging is not available via log4j, the log.xxxx calls in domain classes etc. are just mocked using

mockLogging(ClassUnderTest, true)

The "true" stands for "enable debug". In order to do so, the unit test class must extend GrailsUnitTestCase. If you use mockController(class), it implicitly calls mockLogging(class, false) and therefore you get no debug logging. For details check out the grails sources, esp GrailsUnitTestCase and MockUtils.

In opposite to the above, in an integration test the whole machinery is started and log4j is available.

Here is a thought, you didn t ask this exactly but the same question was asked on the grails user group. I am posting my answer here as well, to spread the knowledge.

If you are explicitly saying def log = org.apache.commons.logging.LogFactory.getLog(this) in your classes rather than relying on dependency injection as was explained on the grails user group you can mock the getLog on the LogFactory.

The below is taken from grails.tests.MockUtils.mockLogging and modified to return the logger.

class LoggingEnabledTestCase extends GrailsUnitTestCase {
protected void setUp() {
        super.setUp()
        registerMetaClass(org.apache.commons.logging.LogFactory)
        org.apache.commons.logging.LogFactory.metaClass. static .getLog = {instance ->

            // This is taken from grails.tests.MockUtils and slightly changed to return a logger.

            // Get the name of the class + the last component of the package
            // (if it the class is in a package).
            def pos = instance.class.name.lastIndexOf( . )
            if (pos != -1) pos = instance.class.name.lastIndexOf( . , pos - 1)
            def shortName = instance.class.name.substring(pos + 1)

            // Dynamically inject a mock logger that simply prints the
            // log message (and optional exception) to stdout.
            def mockLogger = [
                    fatal: {String msg, Throwable t = null ->
                        println "FATAL (${shortName}): $msg"
                        if (t) {
                            println "       Exception thrown - ${t.message}"
                        }
                    },
                    error: {String msg, Throwable t = null ->
                        println "ERROR (${shortName}): $msg"
                        if (t) {
                            println "       Exception thrown - ${t.message}"
                        }
                    },
                    warn: {String msg, Throwable t = null ->
                        println "WARN (${shortName}):  $msg"
                        if (t) {
                            println "       Exception thrown - ${t.message}"
                        }
                    },
                    info: {String msg, Throwable t = null ->
                        println "INFO (${shortName}):  $msg"
                        if (t) {
                            println "       Exception thrown - ${t.message}"
                        }
                    },
                    debug: {String msg, Throwable t = null ->
                        println "DEBUG (${shortName}): $msg"
                        if (t) {
                            println "       Exception thrown - ${t.message}"
                        }
                    },
                    trace: {String msg, Throwable t = null -> },
                    isFatalEnabled: {-> true},
                    isErrorEnabled: {-> true},
                    isWarnEnabled: {-> true},
                    isInfoEnabled: {-> true},
                    isDebugEnabled: {-> true},
                    isTraceEnabled: {-> false}] as Log
            return mockLogger
        }
    }

    protected void tearDown() {
        super.tearDown()
    }
}

Using Grails 1.1.1 and an approximation to your setup, I have a unit test called FooTests.groovy

After running grails test-app, I am able to see the output from the test in the directory:

./test/reports/plain

specifically in the files, as appropriate:

TEST-com.mypackages.FooTests-err.txt
TEST-com.mypackages.FooTests-out.txt
TEST-com.mypackages.FooTests.txt

Note that I see no output in the hibeFile. I m not sure, but I suspect a previous poster is correct in that unit tests don t receive the logging setup.





相关问题
grails + gwt request handling via controllers

I am new to gwt. I am trying to integrate gwt+grails.Can anybody provide me a good example for handling the request using grails controllers and not a custom servlet.I will be really thankful if ...

Error loading the grails gwt module xml

I ve installed the plugin from this article by Peter http://www.cacoethes.co.uk/blog/groovyandgrails/the-command-pattern-w.... While compile time its not able to find the module file which is present ...

Sorting Objects Based on Custom Domain Class Methods

I have a domain class, in which I ve defined some methods which give the object a score based on different algorithms (eg. popularity). I now want to retrieve a list of these objects sorted by one of ...

Grails Packaging and Naming Conventions

Packaging Controllers, Services,etc. i.e. - com.company.controllers - com.company.services Is this a good practice or should be avoided by all means?? Another worth mentioning problem I encountered ...

Hibernate/GORM: collection was not processed by flush()

I have an integration test in my Grails application that fails when I try to save an entity of type Member invitingMember.save(flush: true) This raises the following exception org.hibernate....

热门标签