Groovy Slf4j 注释似乎干扰了 Grails 内置日志记录
Groovy Slf4j annotation appears to be interfering with Grails built-in logging
我创建了一个 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
注释。我终于准备好在本地 运行 myapp
(grails 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
下的所有 packages/classes 配置日志记录,如果我能在我的 log4j 配置中提供某种通配符,如 com.me.myapp.*
,那就太好了
- 任何使用
@Slf4j
注释的 Groovy 类,在我的 Grails 应用程序 (myapp
) 中定义,或在第 3 方 JAR 中定义,必须遵守其日志记录
请注意: 在 Grails 之外,我绝对 喜欢 logback。但根据我的经验,我发现 Grails Logback 插件严重损坏,因此我对在 Grails 应用程序中从 log4j -> logback 切换不感兴趣。
您说得对,info 'com.example.myapp'
本质上是 com.example.myapp.*
的通配符,因此应该可以。我发现当日志记录没有按预期工作并且记录器的名称可能是错误的时,为记录器名称添加 println 语句通常会清除错误配置的内容。因此,例如在控制器或服务中,只需添加
println "logger name for ${getClass().name} is $log.name"
并在调用该控制器操作或服务方法后在控制台中查找该消息。
我创建了一个 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
注释。我终于准备好在本地 运行 myapp
(grails 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
下的所有 packages/classes 配置日志记录,如果我能在我的 log4j 配置中提供某种通配符,如com.me.myapp.*
,那就太好了 - 任何使用
@Slf4j
注释的 Groovy 类,在我的 Grails 应用程序 (myapp
) 中定义,或在第 3 方 JAR 中定义,必须遵守其日志记录
请注意: 在 Grails 之外,我绝对 喜欢 logback。但根据我的经验,我发现 Grails Logback 插件严重损坏,因此我对在 Grails 应用程序中从 log4j -> logback 切换不感兴趣。
您说得对,info 'com.example.myapp'
本质上是 com.example.myapp.*
的通配符,因此应该可以。我发现当日志记录没有按预期工作并且记录器的名称可能是错误的时,为记录器名称添加 println 语句通常会清除错误配置的内容。因此,例如在控制器或服务中,只需添加
println "logger name for ${getClass().name} is $log.name"
并在调用该控制器操作或服务方法后在控制台中查找该消息。