Java日志记录:显示调用方的源行号(而不是日志记录帮助程序方法)

Java 的众多(叹息...)日志记录框架在显示创建日志消息的方法的源文件名的行号方面都做得很好:

log.info("hey");

 [INFO] [Foo:413] hey

但是,如果中间有一个帮助器方法,则实际的调用方将是帮助器方法,这不会提供太多信息。

log_info("hey");

[INFO] [LoggingSupport:123] hey

有没有办法告诉日志记录系统在弄清楚要打印的源位置时从调用堆栈中删除一帧?

我认为这是特定于实现的;我需要的是Log4J通过Commons Logging,但我有兴趣了解其他选项。


答案 1

替代答案。

可以使用该方法要求 log4j 排除帮助程序类

类别.log(字符串调用方FQCN, 优先级, 对象消息, 可抛出 t)

并将帮助程序类指定为“调用方FQCN”。

例如,下面是一个使用帮助程序的类:

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");
}}

和帮助程序的代码:

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);
} }

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

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将照常工作,如果不需要,可以避免计算堆栈跟踪。


答案 2

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

您可以使用以下 API:

    StackTraceElement[] stackTraces = Thread.currentThread().getStackTrace();
    StackTraceElement stackTraceElement = ...;
    stackTraceElement.getLineNumber();

更新:

你必须自己计算。所以:

  • 要求log4j不要输出它(以你的日志记录格式),
  • 并在消息的开头插入行号显式(您发送到log4j的字符串)。

根据您对记录器的偏好,您的帮助程序方法可能会:

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

推荐