java - Log4j2 在方法引用调用中打印实用程序类行号

标签 java lambda log4j2

我有一段代码如下,

List<String> someList = new ArrayList<>();
someList.add("abc1");
someList.add("abc2");
someList.add("abc3");
someList.add("abc4");
someList.add("abc5");

someList.forEach(logger::debug);
someList.forEach(l -> logger.debug(l));

在方法引用样式中,输出如下-

[com.some.pkg.AppContext:1249] abc1
[com.some.pkg.AppContext:1249] abc2
[com.some.pkg.AppContext:1249] abc3
[com.some.pkg.AppContext:1249] abc4
[com.some.pkg.AppContext:1249] abc5

而对于 lambda,输出是预期的。

[com.some.pkg.AppContext:36] abc1
[com.some.pkg.AppContext:36] abc2
[com.some.pkg.AppContext:36] abc3
[com.some.pkg.AppContext:36] abc4
[com.some.pkg.AppContext:36] abc5

模式是[%logger{36}:%L]

此外,如果我使用 %F,则方法引用会打印 ArrayList.java,但 lambda 会打印预期的类。

我不确定我是否遗漏了什么或者这是 log4j2 的错误/限制。

最佳答案

我认为从 log4j2 来看,这是预期的行为。区别在于方法引用和 lambda 表达式在 java 中的执行方式不同。

根据 log4j2 documentation -

If one of the layouts is configured with a location-related attribute like HTML locationInfo, or one of the patterns %C or %class, %F or %file, %l or %location, %L or %line, %M or %method, Log4j will take a snapshot of the stack, and walk the stack trace to find the location information.

简单来说,log4j使用stack trace来确定日志语句的位置信息。

AbstraceLogger类的info()debug()等方法被调用时,会查找当前的堆栈跟踪以确定调用者的位置。

在方法引用的情况下,stack trace 如下所示 -

Method Reference Stack trace

注意从顶部开始的第 3 行 - ArrayList,第 1380 行。我认为第 2 行被忽略,因为它没有给出文件名和行号的有效值。

在 lambda 表达式的情况下,堆栈跟踪 看起来像 -

Lambda Expressions Stack trace

如您所见,两种情况下 debug() 方法的最后一个调用者是不同的,因此行号也是不同的。

使用您提供的代码,我还收到以下日志 -

com.some.pkg.AppContext:1380
com.some.pkg.AppContext:1380
com.some.pkg.AppContext:1380
com.some.pkg.AppContext:1380
com.some.pkg.AppContext:1380
com.some.pkg.AppContext:36
com.some.pkg.AppContext:36
com.some.pkg.AppContext:36
com.some.pkg.AppContext:36
com.some.pkg.AppContext:36

%F 模式的输出差异也与此解释有关。对于 %F 模式,堆栈跟踪 用于查找文件名。 Logger 不需要堆栈跟踪查找。

关于java - Log4j2 在方法引用调用中打印实用程序类行号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48329457/

相关文章:

c++ - 如何限制 C++17 模板参数中的 lambda 签名?

Java:合并 2 个列表 <String[]>

java - 循环以随机显示数组中的图像(Android)

java - 如何在 Android 中为输入音频实现 IIR 带通滤波器

lambda - 什么是调用/抄送?

java - Log4j2:重定向类及其调用链的日志记录语句

java - 用 Java 构建了部分上传系统,但视频损坏

c# - MVC3 如何使用@<text></text> 作为 html 辅助参数

java - Android 上的 Log4j2

java - Log4j2 套接字附加器 "connect java.net.ConnectException: Connection refused: connect"