【问题标题】:Groovy Slf4j annotation appears to be interfering with Grails built-in loggingGroovy Slf4j 注释似乎干扰了 Grails 内置日志记录
【发布时间】:2015-10-22 17:18:30
【问题描述】:

我创建了一个 Grails 2.4.5 应用程序 (grails create-app myapp) 并在 src/groovy 下添加了一堆 Groovy 类。对于任何需要记录的类,我使用了@Slf4j annotation,如下所示:

package com.example.myapp

import groovy.util.logging.Slf4j

@Slf4j
class MyObject {
    def doSomething() {
        log.info('I'm going to do something now.')
    }
}

同样适用于 Grails 生成的类,例如控制器和服务(也就是说,我使用 @Slf4j 注释来表示一切)。我终于准备好在本地运行myappgrails run-app,当我这样做时,我看不到任何 SLF4J 语句记录(无论日志级别如何)。

这是我来自Config.groovy的日志记录配置:

log4j.main = {
    console name: "stdout", layout: pattern(conversionPattern: "%c{2} %m%n")

    info  'com.example.myapp' // I'm hoping this is a wildcard that actually
                              // means 'com.example.myapp.*'

    error  'org.codehaus.groovy.grails.web.servlet',
           'org.codehaus.groovy.grails.web.pages',
           'org.codehaus.groovy.grails.web.sitemesh',
           'org.codehaus.groovy.grails.web.mapping.filter',
           'org.codehaus.groovy.grails.web.mapping',
           'org.codehaus.groovy.grails.commons',
           'org.codehaus.groovy.grails.plugins',
           'org.codehaus.groovy.grails.orm.hibernate',
           'org.springframework',
           'org.hibernate',
           'net.sf.ehcache.hibernate'
}

我知道 Grails 使用 log4j,但认为 Grails 带有自己的 SLF4J 绑定,因此这些 @Slf4j 注释应该可以工作。我尝试将 'org.slf4j:slf4j-log4j12:1.7.5' 放在我的编译路径上,但这也不起作用(并产生 SLF4J 错误,抱怨类路径上有多个绑定;这证实了我的理论,即 Grails 附带了自己的 SLF4J 绑定)。

我需要做什么才能让日志记录在这里工作?这是我需要的:

  • 我需要为 com.me.myapp 下的所有包/类配置日志记录,如果我可以在我的 log4j 配置中提供某种通配符,例如 com.me.myapp.*,那就太好了
  • 任何使用 @Slf4j 注释、在我的 Grails 应用程序 (myapp) 中定义或在 3rd 方 JAR 中定义的 Groovy 类,都必须遵守其日志记录

请注意:在 Grails 之外,我绝对喜欢 logback。但根据我的经验,我发现 Grails Logback 插件严重损坏,因此我对在 Grails 应用程序中从 log4j -> logback 切换不感兴趣。

【问题讨论】:

    标签: grails logging log4j slf4j


    【解决方案1】:

    你说得对,info 'com.example.myapp' 本质上是com.example.myapp.* 的通配符,所以应该可以。我发现当日志记录不能按预期工作并且记录器的名称可能有误时,为记录器名称添加 println 语句通常会清除错误配置的内容。因此,例如在控制器或服务中,只需添加

    println "logger name for ${getClass().name} is $log.name"
    

    并在调用该控制器操作或服务方法后在控制台中查找该消息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-26
      • 2011-11-07
      相关资源
      最近更新 更多