【问题标题】:Grails log4j configurationGrails log4j 配置
【发布时间】:2010-12-18 10:32:10
【问题描述】:

我多次遇到 Grails 在 1.1 版中引入的用于配置 Log4J 的 DSL 的问题。我当前的配置如下所示:

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
    }
}

这里的意图是:

  • 在调试级别记录com.mypackages,在错误级别记录所有其他内容
  • 将所有输出记录到名为 hibeFile 的文件和控制台中

当我运行应用程序或集成测试时,这可以正常工作。但是,当我运行单元测试时,控制台中或 Grails 测试报告中显示的“System.out”或“System.err”链接中都不会出现日志记录。运行单元测试时如何查看我的日志?

谢谢, 唐

【问题讨论】:

    标签: grails log4j


    【解决方案1】:

    AFAIK,在运行 Grails 单元测试时,无法通过 log4j 获得整个日志记录,域类中的 log.xxxx 调用等只是被模拟使用

    mockLogging(ClassUnderTest, true)
    

    “true”代表“启用调试”。为此,单元测试类必须扩展 GrailsUnitTestCase。 如果您使用 mockController(class),它会隐式调用 mockLogging(class, false),因此您不会获得调试日志记录。有关详细信息,请查看 grails 源代码,尤其是 GrailsUnitTestCase 和 MockUtils。

    与上述相反,在集成测试中,整个机器被启动并且 log4j 可用。

    【讨论】:

    • 那么如何测试一个充斥着日志语句的控制器呢?我现在有这个问题??
    • 在测试的 setUp() 方法中使用 mockLogging(MyDamnCoolCOntroller, true)。
    【解决方案2】:

    这是一个想法,您并没有确切地问这个问题,但是在 grails 用户组上也提出了同样的问题。我也在这里发布我的答案,以传播知识。

    如果你在你的类中明确说 def log = org.apache.commons.logging.LogFactory.getLog(this) 而不是像 grails 用户组中解释的那样依赖依赖注入,你可以在 LogFactory 上模拟 getLog .

    以下内容取自 grails.tests.MockUtils.mockLogging 并修改为返回记录器。

    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()
        }
    }
    

    【讨论】:

      【解决方案3】:

      使用 Grails 1.1.1 和您的设置的近似值,我有一个名为 FooTests.groovy 的单元测试

      运行grails test-app后,我可以在目录中看到测试的输出:

      ./test/reports/plain
      

      具体在文件中,视情况而定:

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

      请注意,我在 hibeFile 中没有看到任何输出。我不确定,但我怀疑以前的海报是正确的,因为单元测试没有收到日志记录设置。

      【讨论】:

        猜你喜欢
        • 2017-09-24
        • 1970-01-01
        • 1970-01-01
        • 2023-03-25
        • 2011-09-18
        • 1970-01-01
        • 2015-04-28
        • 2013-09-12
        • 1970-01-01
        相关资源
        最近更新 更多