【问题标题】:Using multiple loggers on a single appender在单个 appender 上使用多个记录器
【发布时间】:2013-08-26 15:37:01
【问题描述】:

以下是我的日志记录配置。它记录的正是我想要的,但它只是将它记录到一个文件中。我想在控制台上看到相同的信息。我尝试了几种变体,但对于每种变体,我只能将信息记录到控制台或文件中,而不是两者。

    def appName = grails.util.Metadata.current.'app.name'
    def catalinaBase = System.properties.getProperty('catalina.base')
    catalinaBase = catalinaBase ?: "."
    def logDirectory = "${catalinaBase}${File.separator}logs${File.separator}${appName}"

    // log4j configuration
    log4j = {
        appenders {
            rollingFile name: 'stdout',     file: "${logDirectory}${File.separator}${appName}.log".toString(), maxFileSize: '100MB' // Use the same file for stdout and stacktrace
            rollingFile name: 'stacktrace', file: "${logDirectory}${File.separator}${appName}.log".toString(), maxFileSize: '100MB' // Use the same file for stdout and stacktrace
        }

        warn   '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',
               'net.sf.ehcache.hibernate'

        all    'grails.app.controllers.test',
               'grails.app.domain.test',
               'grails.app.services.test',
               'grails.app.taglib.test',
               'grails.app.conf.test',
               'grails.app.filters.test'
    }

【问题讨论】:

    标签: grails log4j


    【解决方案1】:

    首先,让两个不同的 appender 记录到同一个文件是一个坏主意,如果您希望完整的堆栈跟踪与普通日志转到同一个位置,那么您应该重新指向 logger 级别而不是 appender 级别。

    对于您的实际问题,我会创建一个控制台附加程序和一个文件附加程序,并将它们都附加到 root 记录器。

    log4j = {
      appenders {
        console name:'stdout'
        rollingFile name: 'applog',     file: "${logDirectory}${File.separator}${appName}.log".toString(), maxFileSize: '100MB'
        'null' name:'stacktrace' // prevent Grails trying to create stacktrace.log
      }
    
      root {
        warn 'stdout', 'applog'
      }
    
      // Send full stack traces to the main appName.log file
      warn applog:'StackTrace'
    
      // individual warn/all logger configurations as before
    }
    

    这会将相同的日志发送到标准输出和日志文件,但只会将完整的堆栈跟踪发送到文件(而不是控制台)。如果您确实也想要控制台上的完整堆栈跟踪,请将其更改为

      warn applog:'StackTrace', stdout:'StackTrace'
    

    或者,您可以考虑完全禁用 StackTrace 记录器(删除整个 warn applog:'StackTrace' 行),然后通过将系统属性 grails.full.stacktrace 设置为 true 来禁用堆栈跟踪过滤,这样您就可以获得完整的未过滤堆栈跟踪记录普通的记录器。

    【讨论】:

    • 谢谢!我想这明白了。不过我很好奇,为什么让两个附加程序记录到同一个文件是不好的?没有任何锁定的机会吗?我发现当堆栈跟踪与应用日志中的信息处于同一上下文时,它更容易调试。
    • @ubiquibacon 对于普通的 FileAppender,您可能会侥幸逃脱(我不确定),但对于滚动文件,我会担心如果两者都发生会发生什么appender 尝试同时滚动日志文件(或者更糟,在稍微不同的时间 - appender 1 将 app.log 重命名为 app.log.1 并打开一个新的 app.log,appender 2 然后将新的 app.log 重命名为app.log.1 并且您丢失了原始日志文件)。
    • 我现在看到,默认情况下,stdout 中似乎包含部分堆栈跟踪。这实际上就是我想要的,所以我不必将完整的堆栈跟踪合并到应用程序日志中来获得我想要的。感谢您让我走上正轨。
    【解决方案2】:

    使用上述配置,例如,要将所有 INFO 级别的“grails.app”事件记录到控制台和“stdout”附加程序,您需要以下内容:

    log4j = {
       appenders { 
         ... appender configuration here ...
       }
       // configure a root logger
       root {
         warn 'stdout'
         additivity = false
       }
    
       info stdout:'grails.app'
       info console:'grails.app'
    
    }
    

    【讨论】:

    • 你愿意提供一个例子吗?我已经阅读了文档,但我不知道这会有什么帮助。我想要的是在单个附加程序上使用多个记录器。 Grails Logging Excerpt可加性只是确定记录器是否从其父级继承配置。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-13
    • 1970-01-01
    • 2017-10-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多