Java Logging:显示调用者的源行号(不是日志助手方法)

Thi*_*ilo 44 java logging log4j apache-commons-logging

Java的众多(叹息......)日志框架都可以很好地显示创建日志消息的方法的源文件名的行号:

log.info("hey");

 [INFO] [Foo:413] hey
Run Code Online (Sandbox Code Playgroud)

但是如果在它们之间有一个辅助方法,那么实际的调用者将是辅助方法,并且这不是太多的信息.

log_info("hey");

[INFO] [LoggingSupport:123] hey
Run Code Online (Sandbox Code Playgroud)

有没有办法告诉日志系统在确定要打印的源位置时从callstack中删除一个帧?

我想这是特定于实现的; 我需要的是Log4J通过Commons Logging,但我很想知道其他选项.

vdr*_*vdr 34

替代答案.

可以通过使用该方法让log4j排除帮助程序类

Category.log(String callerFQCN,Priority level,Object message,Throwable t)

并将帮助程序类指定为'callerFQCN'.

例如,这是一个使用帮助器的类:

public class TheClass {
    public static void main(String...strings) {
        LoggingHelper.log("Message using full log method in logging helper.");
        LoggingHelper.logNotWorking("Message using class info method");
}}
Run Code Online (Sandbox Code Playgroud)

和助手的代码:

public class LoggingHelper {
private static Logger LOG = Logger.getLogger(LoggingHelper.class);

public static void log(String message) {
    LOG.log(LoggingHelper.class.getCanonicalName(), Level.INFO, message, null);
}

public static void logNotWorking(String message) {
    LOG.info(message);
} }
Run Code Online (Sandbox Code Playgroud)

第一种方法将输出您的预期结果.

Line(TheClass.main(TheClass.java:4)) Message using full log method in logging helper.
Line(LoggingHelper.logNotWorking(LoggingHelper.java:12)) Message using class info method

使用此方法时,Log4j将照常工作,如果不需要,则避免计算堆栈跟踪.


KLE*_*KLE 5

请注意,提供行号是非常昂贵的,无论是从Log4j或以下自然获得的.你必须接受这个成本......

您可以使用以下API:

    StackTraceElement[] stackTraces = Thread.currentThread().getStackTrace();
    StackTraceElement stackTraceElement = ...;
    stackTraceElement.getLineNumber();
Run Code Online (Sandbox Code Playgroud)

更新:

你必须自己计算.所以:

  • 请求log4j不输出它(以您的日志格式),
  • 并在消息的开头插入行号explicitement(发送到log4j的String).

根据您喜欢的记录器,您的帮助方法可能:

  • 在适当的时候使用显式Logger(作为参数传递)(我们有时会为特定的上下文定义特定的记录器;例如,我们有一个记录器用于发送我们的数据库请求,无论它是什么类;这允许我们减少当我们想要(取消)激活它们时,在一个地方对我们的配置文件进行更改...)
  • 使用Logger作为调用类:在这种情况下,您可以同样推导出调用者类名称,而不是传递参数.