logback 不打印方法或行号
logback doesn't print method or line number
这是一个 Gradle 项目,使用 Groovy 作为应用程序代码和测试代码。但是我正在使用 logback.xml 文件进行配置。
这里可能重要的一个因素是我使用 Groovy @Slf4j 注释来提供记录器。
%method
和 %line
转换词通常分别打印为 "invoke" 和“-1”(尽管有时 "invoke0" 和“-2”)。
有趣的是,它有时会打印方法和编号:例如当它是带有 Exception
参数的 ERROR
级别日志时:
log.error( 'indexSearcher.indexReader.close() threw Exception', e )
...我认为这与携带它的 e
对象有关 "location" 数据,然后 logback 可以利用这些数据。但偶尔会打印一条 INFO
级别的消息,其中包含方法和行号:这很令人费解。
我见过有人对异步附加程序有问题,但我的附加程序是 ROLLING_FILE (RollingFileAppender)。这不是异步附加程序的扩展。
我尝试了其他 SO 问题中记录的其他补救措施(例如 here):我已将这些行添加到我的附加程序中:
<includeCallerData>true</includeCallerData>
<param name="locationInfo" value="true" />
...没有解决问题
某处有人说有必要确保在某些时候打开调试数据。在 Groovy 的情况下,我不确定如何尝试这个想法。
logback.groovy
appender("STDOUT", ConsoleAppender) {
encoder(PatternLayoutEncoder) {
pattern = "%d{HH:mm:ss.SSS} [%thread] %-5level {%logger} - %class.%method:%line - %msg%n"
}
}
root(DEBUG, ["STDOUT"])
X.groovy
@GrabConfig(systemClassLoader=true)
@GrabResolver(name='maven2',root='http://repo1.maven.org/maven2/')
@Grab(group='ch.qos.logback', module='logback-classic', version='1.2.3')
@Grab(group='org.slf4j', module='slf4j-api', version='1.7.30')
import groovy.util.logging.Slf4j
@Slf4j
class A {
def f() {
log.info 'msg-info-2' //line 11
log.with{
info 'msg-info-1' //line 13
//new Exception("test").printStackTrace(System.out)
}
}
}
def a = new A()
a.f()
命令 groovy X.groovy
打印:
12:24:43.134 [main] INFO {A} - A.f:11 - msg-info-1
12:24:43.139 [main] INFO {A} - sun.reflect.NativeMethodAccessorImpl.invoke0:-2 - msg-info-2
为什么
在 logback 中有一个 class CallerData 方法 extract
提取调用者数据信息作为基于 Throwable
参数和 returns 的数组StackTraceElement
的数组。它试图清除堆栈跟踪,但是对于 groovy 它可能真的很复杂。
例如,如果您取消注释行 new Exception("test").printStackTrace(System.out)
您会看到这样的堆栈跟踪:
java.lang.Exception: test
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
... + 11 elements
at A$_f_closure1.doCall(X.groovy:14)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
... + 15 elements
at A.f(X.groovy:12)
... + 20 elements
CallerData 尝试跳过堆栈跟踪中的技术 groovy 元素,但未能检测到正确的元素。
解决方案
可以修改 logback 上下文的 Framework Packages
。
我不知道如何从 logback.xml
做到这一点,但我找到了如何使用 logback.groovy
做到这一点
logback.groovy(修改)
也许对于你的情况你必须添加另一个框架(忽略)包...
context.getFrameworkPackages().addAll([
"sun.reflect",
"java.lang.reflect",
"org.codehaus.groovy",
"groovy.lang.MetaMethod",
"jdk.internal.reflect"
])
appender("STDOUT", ConsoleAppender) {
encoder(PatternLayoutEncoder) {
pattern = "%d{HH:mm:ss.SSS} [%thread] %-5level {%logger} - %class.%method:%line - %msg%n"
}
}
root(DEBUG, ["STDOUT"])
使用此配置,上面的代码可以正确打印行:
13:12:14.410 [main] INFO {A} - A.f:11 - msg-info-2
13:12:14.416 [main] INFO {A} - A$_f_closure1.doCall:13 - msg-info-1
这是一个 Gradle 项目,使用 Groovy 作为应用程序代码和测试代码。但是我正在使用 logback.xml 文件进行配置。
这里可能重要的一个因素是我使用 Groovy @Slf4j 注释来提供记录器。
%method
和 %line
转换词通常分别打印为 "invoke" 和“-1”(尽管有时 "invoke0" 和“-2”)。
有趣的是,它有时会打印方法和编号:例如当它是带有 Exception
参数的 ERROR
级别日志时:
log.error( 'indexSearcher.indexReader.close() threw Exception', e )
...我认为这与携带它的 e
对象有关 "location" 数据,然后 logback 可以利用这些数据。但偶尔会打印一条 INFO
级别的消息,其中包含方法和行号:这很令人费解。
我见过有人对异步附加程序有问题,但我的附加程序是 ROLLING_FILE (RollingFileAppender)。这不是异步附加程序的扩展。
我尝试了其他 SO 问题中记录的其他补救措施(例如 here):我已将这些行添加到我的附加程序中:
<includeCallerData>true</includeCallerData>
<param name="locationInfo" value="true" />
...没有解决问题
某处有人说有必要确保在某些时候打开调试数据。在 Groovy 的情况下,我不确定如何尝试这个想法。
logback.groovy
appender("STDOUT", ConsoleAppender) {
encoder(PatternLayoutEncoder) {
pattern = "%d{HH:mm:ss.SSS} [%thread] %-5level {%logger} - %class.%method:%line - %msg%n"
}
}
root(DEBUG, ["STDOUT"])
X.groovy
@GrabConfig(systemClassLoader=true)
@GrabResolver(name='maven2',root='http://repo1.maven.org/maven2/')
@Grab(group='ch.qos.logback', module='logback-classic', version='1.2.3')
@Grab(group='org.slf4j', module='slf4j-api', version='1.7.30')
import groovy.util.logging.Slf4j
@Slf4j
class A {
def f() {
log.info 'msg-info-2' //line 11
log.with{
info 'msg-info-1' //line 13
//new Exception("test").printStackTrace(System.out)
}
}
}
def a = new A()
a.f()
命令 groovy X.groovy
打印:
12:24:43.134 [main] INFO {A} - A.f:11 - msg-info-1
12:24:43.139 [main] INFO {A} - sun.reflect.NativeMethodAccessorImpl.invoke0:-2 - msg-info-2
为什么
在 logback 中有一个 class CallerData 方法 extract
提取调用者数据信息作为基于 Throwable
参数和 returns 的数组StackTraceElement
的数组。它试图清除堆栈跟踪,但是对于 groovy 它可能真的很复杂。
例如,如果您取消注释行 new Exception("test").printStackTrace(System.out)
您会看到这样的堆栈跟踪:
java.lang.Exception: test
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
... + 11 elements
at A$_f_closure1.doCall(X.groovy:14)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
... + 15 elements
at A.f(X.groovy:12)
... + 20 elements
CallerData 尝试跳过堆栈跟踪中的技术 groovy 元素,但未能检测到正确的元素。
解决方案
可以修改 logback 上下文的 Framework Packages
。
我不知道如何从 logback.xml
做到这一点,但我找到了如何使用 logback.groovy
logback.groovy(修改)
也许对于你的情况你必须添加另一个框架(忽略)包...
context.getFrameworkPackages().addAll([
"sun.reflect",
"java.lang.reflect",
"org.codehaus.groovy",
"groovy.lang.MetaMethod",
"jdk.internal.reflect"
])
appender("STDOUT", ConsoleAppender) {
encoder(PatternLayoutEncoder) {
pattern = "%d{HH:mm:ss.SSS} [%thread] %-5level {%logger} - %class.%method:%line - %msg%n"
}
}
root(DEBUG, ["STDOUT"])
使用此配置,上面的代码可以正确打印行:
13:12:14.410 [main] INFO {A} - A.f:11 - msg-info-2
13:12:14.416 [main] INFO {A} - A$_f_closure1.doCall:13 - msg-info-1