为啥 stacktrace.log 没有在 grails 3 中填充 logback?

Posted

技术标签:

【中文标题】为啥 stacktrace.log 没有在 grails 3 中填充 logback?【英文标题】:Why does stacktrace.log not fill with logback in grails 3?为什么 stacktrace.log 没有在 grails 3 中填充 logback? 【发布时间】:2016-08-11 22:06:01 【问题描述】:

当您创建一个新的 grails 应用程序时,默认的 logback.groovy 文件(以及几乎每个 logback.groovy 示例,甚至是 Mr Haki's example)都包含以下代码,我已对其进行了简化以专注于相关部分:

root(ERROR, ['STDOUT'])

appender("FULL_STACKTRACE", FileAppender) 
    file = "build/stacktrace.log"
    append = true
    encoder(PatternLayoutEncoder) 
        pattern = "%level %logger - %msg%n"
    

logger("StackTrace", ERROR, ['FULL_STACKTRACE'], false )

但是,遵循这种方法不会导致错误输出到 stacktrace.log 文件。

@JeffScottBrown 的答案包含以下 Bootstrap.groovy 文件,用于测试堆栈跟踪是否按预期记录:

class BootStrap 

    def init =  servletContext ->
        log.error 'this is a new error'
    
    def destroy = 
    

使用该引导文件,运行 grails 应用程序不会产生任何输出到 build/stacktrace.log

如果您删除 StackTrace 记录器,并将 FULL_STACKTRACE 添加到根记录器:

root(ERROR, ['STDOUT', 'FULL_STACKTRACE']

您将在 stacktrace.log 中获得输出。

或者,将 StackTrace 记录器重命名为 grails.app.init.Bootstrap(感谢 @JeffScottBrown 提供此行):

logger 'grails.app.init.BootStrap', ERROR, ['FULL_STACKTRACE'], false

你会得到输出到stacktrace.log

这个观察让我相信StackTrace 记录器没有做任何事情。我进一步被引导相信任何没有为包命名的记录器都不起作用。

因此,我的问题是:

logback 是否适用于非包/类命名的记录器? 如果是这样,为什么默认 logback.groovy 中的 StackTrace 记录器不会导致输出到 stacktrace.log?

编辑:

对我来说主要问题是 StackTrace 记录器似乎完全没有必要,那么为什么将它包含在默认文件中?

第二次编辑:

确认这一点的另一种方法是仅让 StackTrace 记录器写入 STDOUT 附加程序,并在您抛出异常时观察堆栈跟踪从控制台消失:

logger("StackTrace", ERROR, ['STDOUT','FULL_STACKTRACE'], false) root(ERROR, [])

【问题讨论】:

这是与 Grails 3.1.0.RC2 一起使用的。我会尝试在某个时候使用更高版本进行测试。 它有效。检查 grails 项目的build 目录。 @Kowser 有什么用?你是说你的 logback.groovy 只有一个使用FULL_STACKTRACE appender 的记录器,即StackTrace 记录器定义为:logger("StackTrace", ERROR, ['FULL_STACKTRACE'], false )?如果您有任何其他使用FULL_STACKTRACE 的记录器,那么您将绕过我认为无用的行。 【参考方案1】:

我希望您没有将附加程序配置为正确使用。

以下作品:

import grails.util.BuildSettings
import grails.util.Environment

// See http://logback.qos.ch/manual/groovy.html for details on configuration
appender('STDOUT', ConsoleAppender) 
    encoder(PatternLayoutEncoder) 
        pattern = "%level %logger - %msg%n"
    


root(ERROR, ['STDOUT'])

def targetDir = BuildSettings.TARGET_DIR
if (Environment.isDevelopmentMode() && targetDir) 
    appender("FULL_STACKTRACE", FileAppender) 
        file = "$targetDir/stacktrace.log"
        append = true
        encoder(PatternLayoutEncoder) 
            pattern = "%level %logger - %msg%n"
        
    
    logger("StackTrace", ERROR, ['FULL_STACKTRACE'], false)


logger 'grails.app.init.BootStrap',
        ERROR, ['FULL_STACKTRACE'], false

在 BootStrap.groovy...

class BootStrap 

    def init =  servletContext ->
        log.error 'this is a new error'
    
    def destroy = 
    

该错误出现在stacktrace.log

编辑以解决新问题:

logback 是否适用于非包/类命名的记录器?

是的。

如果是这样,为什么默认 logback.groovy 中的 StackTrace 记录器 不会导致输出到 stacktrace.log?

StackTrace 记录器确实会导致将输出写入与相应附加程序关联的所有记录器的 stacktrace.log。

【讨论】:

这不能回答我想到的问题,所以我想我需要编辑我的问题...我的主要问题是 logger("StackTrace", ERROR... 行作为示例出现在很多地方,但它不起作用。您的回答并不表明它有效,它表明您还需要一些东西。那有意义吗?我将编辑我的问题以澄清。 我已经编辑了问题以实际询问我的想法。 @RyanHeathcote “但它不起作用” - 据我所知,它确实起作用。如果不是,请创建一个演示该问题的示例应用并分享指向该问题的链接。 我无法判断这种混淆是否与误解日志级别、附加程序或是否真的存在错误有关。描述您期望工作的示例应用程序将阐明这一点。 让我困惑的是为什么logger("StackTrace", ERROR... 行是必要的。在我的实验中,没有任何其他记录器使用FULL_STACKTRACE appender,它什么都不做,没有它我可以将输出输出到 stacktrace.log 文件中。【参考方案2】:

改变

logger("StackTrace", ERROR, ['FULL_STACKTRACE'], false )

logger("grails.app", INFO, ['FULL_STACKTRACE'], false)

将grails-app中的所有日志写入stacktrace.log

【讨论】:

【参考方案3】:

您在 Bootstrap.groovy 中的日志语句:

log.error 'this is a new error'

将常规错误级别消息记录到名为grails.app.init.yourapp.BootStrap 的记录器。它不会记录到名为StackTrace 的记录器。 FULL_STACKTRACE appender 用于未过滤的堆栈跟踪。这些由框架写入记录器StackTrace

如果你替换

log.error 'this is a new error'

throw new RuntimeException("foo")

您将看到完整的堆栈跟踪记录到 stacktrace.log

【讨论】:

我试过这个,根据我所看到的,当root 记录器附加到FULL_STACKTRACE 附加程序时,异常只会导致堆栈跟踪转储到 stacktrace.log。我仍然没有看到堆栈跟踪或任何专门通过StackTrace 记录器路由的东西。当我尝试通过STDOUT 专门路由StackTrace 时,我没有得到任何输出。例如logger("StackTrace", ERROR, ['STDOUT','FULL_STACKTRACE'], false) root(ERROR, [])【参考方案4】:

因此,我的问题是:

logback 是否适用于非包/类命名的记录器?

是的,无论记录器名称如何,logback 都可以工作。

如果是这样,为什么默认 logback.groovy 中的 StackTrace 记录器不会输出到 stacktrace.log?

确实如此。我无法重现它没有的场景。如果可以,请在https://github.com/grails/grails-core/issues 提出问题并附上示例应用程序,我们会对其进行整理。

很抱歉给您带来麻烦,感谢您的反馈。

【讨论】:

以上是关于为啥 stacktrace.log 没有在 grails 3 中填充 logback?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 sed 会因国际字符而失败以及如何解决?

为啥转发的请求会再次通过过滤器链?

为啥我的渐变层覆盖了我的 collectionView 单元格?

[POI2010]GRA-The Minima Game

灰色关联度分析法(GRA)_python

为啥需要更新器/更新函数来更新 React Relay 和 Apollo 客户端中的本地缓存?