Log4j 2 API

Log Builder

传统上,Log4j 已与日志记录语句一起使用,例如

logger.error("Unable to process request due to {}", code, exception);

对于异常是消息的参数还是 Log4j 是否将其作为可抛出对象进行处理,这引起了一些困惑。为了使日志记录更清晰,已将构建器模式添加到 API。使用构建器语法,以上将被处理为:

logger.atError().withThrowable(exception).log("Unable to process request due to {}", code);

使用这种语法,很明显 Log4j 将异常视为 Throwable。

现在,当调用任何 atTrace,atDebug,atInfo,atWarn,atError,atFatal,always 或 atLevel(Level)方法时,Logger 类都将返回 LogBuilder。然后,logBuilder 允许在事件被记录之前将 Marker,Throwable 和/或位置添加到事件中。调用 log 方法总是导致 log 事件被完成并发送。

具有 Marker,Throwable 和位置的日志记录语句如下所示:

logger.atInfo().withMarker(marker).withLocation().withThrowable(exception).log("Login for user {} failed", userId);

在 LogBuilder 上提供定位方法具有两个明显的优点:

  • 日志包装器可以使用它来提供 Log4j 使用的位置信息。

  • 使用无参数的定位方法时捕获位置信息的开销比必须在需要时计算位置信息要好得多。 Log4j 可以简单地在固定索引处请求堆栈跟踪条目,而不必遍历堆栈跟踪来确定调用类。当然,如果布局不使用位置信息,则会导致性能降低。

Location Performance

下表显示了配置为使用 4 个线程时,log4j-perf 项目中 FileAppenderBenchmark 和 FileAppenderWithLocationBenchmark 类的一些结果。结果表明,懒惰地包含位置信息比不包含位置信息慢了大约 8 倍。使用 LogBuilder 的 withLocation 方法比延迟计算位置信息快大约 3 倍,但比不包括位置信息慢大约 2.5 倍。

这些测试是在 2018 年 MacBook Pro 上运行的,该版本使用 2.9 GHz Intel Core i9 处理器(具有 6 核,32 GB 内存和 1 TB SSD 存储)在 Java 11 上使用 Log4j 2.13.0 和 Logback 1.2.3.

Location Performance

Test打印位置信息没有打印位置信息
Log4j2 File191,509.724±11339.978 ops/s1,407,329.130±22595.997 ops/s
具有 Location()的 Log4j2 日志生成器469,200.684±50025.985 ops/s577,127.463±11464.342 ops/s
Logback File159,116.538±1884.969 ops/s1,240,438.384±76619.873 ops/s

不出所料,当使用 LogBuilder 调用 withLocation()方法时,在输出中使用位置信息时,日志记录要快得多,而在没有使用位置信息时,记录要慢得多。

注意:在不同时间运行测试会产生不同的结果。尽管有些结果要高出 10%,但所有结果通常都受到类似的影响,因此它们之间的比较保持不变。