从 gradle 启用 log4j 的调试符号

Enable debug symbols for log4j from gradle

我的 log4j 语句显示行号 ?s。

我试过的

网络上的其他答案说当您没有将调试信息编译到 类 中时会发生这种情况。例如,在 Ant 中,这将通过 <javac debug="true" ... 完成。在 gradle 中搜索执行此操作的方法仅产生

http://gradle.org/docs/2.3-rc-2/dsl/org.gradle.api.tasks.compile.CompileOptions.html

debug - Tells whether to include debugging information in the generated class files. Defaults to true

我通过将 println compileGroovy.options.debug 放入我的 build.gradle 并打印 true 来验证这一点。我还发现 http://forums.gradle.org/gradle/topics/compile-groovy-with-debugging-information,建议使用 tasks.withType(GroovyCompile) { options.debug = true },但也没有用。最后,我找到了compileGroovy.options.debugOptions.debugLevel,它可以有sourcelinesvars。这个默认是null,但是设置成source,lines没有给我线路信息

正在复制

gradle init --type groovy-library

编辑 src/main/groovy/Library.groovy 以获得额外的行:

import groovy.util.logging.Log4j
@Log4j
class Library {
    boolean someLibraryMethod() {
       log.info "XXXXXXXXXXXXX"
       true
    }
}

添加 compile 'log4j:log4j:1.2.17' 到 build.gradle

添加文件src/main/resources/log4j.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
   <appender name="console" class="org.apache.log4j.ConsoleAppender">
       <layout class="org.apache.log4j.PatternLayout">
               <param name="ConversionPattern" value="%d %c:%L - %m%n" />
       </layout>
   </appender>
   <root>
           <level value="INFO" />
           <appender-ref ref="console" />
   </root>
</log4j:configuration>

最后 运行 gradle clean test -i 观察你看到 2015-03-30 08:47:31,996 Library:? - XXXXXXXXXXXXX 请注意消息中的 ?

版本信息

$ gradle -version

------------------------------------------------------------
Gradle 2.3
------------------------------------------------------------

Build time:   2015-02-16 05:09:33 UTC
Build number: none
Revision:     586be72bf6e3df1ee7676d1f2a3afd9157341274

Groovy:       2.3.9
Ant:          Apache Ant(TM) version 1.9.3 compiled on December 23 2013
JVM:          1.8.0_40 (Oracle Corporation 25.40-b25)
OS:           Windows 7 6.1 amd64

$ groovy -version
Groovy Version: 2.4.3 JVM: 1.8.0_40 Vendor: Oracle Corporation OS: Windows 7

$ java -version
java version "1.8.0_40"
Java(TM) SE Runtime Environment (build 1.8.0_40-b26)
Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, mixed mode)

当然,我的问题是如何显示行号而不是问号?

Groovy 包含 class 文件中的行号。问题是 groovy 调用方法与 Java 略有不同,这混淆了确定行号的 Log4j 代码。

特别是,如果您更改行

log.info "XXXXXXXXXXXXX"

log.error "XXXXXXXXXXXXX", new Exception('test')

你可以看到在groovy调用方法时调用了一些反射方法。我生成的堆栈跟踪中最顶层的方法是 sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method),作为本机方法,它没有行号。这就是 Log4j 所关注的。不幸的是,要过滤 Log4j 使用的堆栈跟踪或告诉 Log4j 进一步查看堆栈并不容易。

一种可能的解决方案是打开静态编译。如果您将 @groovy.transform.CompileStatic 添加到库 class 或方法中,您将获得正确的行号。