Log4j2:如何在不使用Throwable的情况下获取类名和行号?

时间:2015-01-20 19:55:41

标签: java logging log4j log4j2

我在Log4j2上开发了一个包装类。使用OSGi的声明性服务我使用自己的记录器接口发布了一个自定义记录器服务,其中包装类是实现。包装器类仅用于以编程方式配置记录器,消息格式化和添加一些方法,最后调用Log4j2的日志记录方法。

我想打印日志文件中请求的每个日志的源类/文件名和行号。选项%C /%F和%L仅打印有关我实际调用 log 方法的包装器类中的位置的信息。

因此,作为锻炼,我每次都将 new Throwable 作为参数传递,以便我可以使用布局%throwable {short.lineNumber} 。但这对嵌入式应用来说是一个昂贵的过程。

我的主要问题在于获取行号,因为对于文件名,我至少可以从Log4j2请求一个新的记录器,其中每个服务的名称都要求记录器服务并将其保存在映射中。

是否有追溯调用者的解决方案?我希望对于您不希望在记录器服务的每个使用者上都有LOG4j2 jar的应用程序有类似的解决方案。仅供参考,我不想使用任何XML文件,所有配置都是以编程方式进行的。

2 个答案:

答案 0 :(得分:4)

您可以使用

StackTraceElement[] stes = Thread.currentThread().getStackTrace();
但是我不确定这会便宜得多。

我所做的是让每条消息都是唯一的(针对班级)并避免包含行号。您可以在IDE中搜索唯一消息以查找行号。该类应该在记录器的名称中。

答案 1 :(得分:2)

Log4j2在内部遍历堆栈跟踪以提取位置信息。它通过为org.apache.logging.log4j.spi.ExtendedLogger#logMessage方法指定正确的FQCN(完全限定的类名)来知道在堆栈跟踪中停止的位置。

Log4j2包含一个为记录器包装器生成代码的工具。文档在此处(在“自定义日志级别”手册页中): http://logging.apache.org/log4j/2.x/manual/customloglevels.html#CustomLoggers

尝试使用此工具生成记录器包装器,并将自定义包装器基于生成的代码。生成的代码将使用正确的FQCN,并能够生成正确的位置信息。