Grails log4j 配置

发布于 2024-08-12 01:05:21 字数 760 浏览 2 评论 0原文

我多次遇到 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”链接中都没有出现任何日志记录。运行单元测试时如何查看我的日志?

谢谢, 大学教师

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

秉烛思 2024-08-19 01:05:21

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

mockLogging(ClassUnderTest, true)

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

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

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.

墨落画卷 2024-08-19 01:05:21

这是一个想法,您没有确切地问这个问题,但在 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()
    }
}

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()
    }
}
最丧也最甜 2024-08-19 01:05:21

使用 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 中没有看到任何输出。我不确定,但我怀疑之前的海报是正确的,因为单元测试没有收到日志记录设置。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文