Apache Log4j2 API官方使用指南(二) —— LogBuilder的使用 以及 性能对比

LogBuilder

Log4j has traditionally been used with logging statements like
Log4j通常被用做如下的logging语句

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

This has resulted in some confusion as to whether the exception should be a parameter to the message or if Log4j should handle it as a throwable. In order to make logging clearer a builder pattern has been added to the API. Using the builder syntax the above would be handled as:
这导致了一些混淆,比如异常应该是消息的一个参数,还是Log4j应该将其作为一个throwable处理。为了使日志记录更清晰,API中添加了一个生成器模块builder pattern。使用生成器语法,可以将上述logging操作改写为:

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

With this syntax it is clear that the exception is to be treated as a Throwable by Log4j.
通过这种语法,就清晰表明这个exception会被Log4j当做一个Throwable处理。

The Logger class now returns a LogBuilder when any of the atTrace, atDebug, atInfo, atWarn, atError, atFatal, always, or atLevel(Level) methods are called. The logBuilder then allows a Marker, Throwable, and/or location to be added to the event before it is logged. A call to the log method always causes the log event to be finalized and sent.
现在,当调用atTrace、atDebug、atInfo、atWarn、atError、atFatal、always或atLevel(Level)方法时,Logger类都会返回一个LogBuilder。然后,logBuilder允许事件在被记录之前,Marker、Throwable 或者/和 location可被添加到事件中。调用log方法,最终都会导致日志事件被终止并发送。

A logging statement with a Marker, Throwable, and location would look like:
一个带有Marker,Throwable和地址信息的logging语句是这样的:

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

这边的withLocation方法有带参数和不带参数两个:可以参考一下链接:
api LINK

default LogBuilder withLocation()
default LogBuilder withLocation(StackTraceElement location)

Providing the location method on the LogBuilder provides two distinct advantages:
在LogBuilder上提供定位方法具有两个明显的优势:

  1. Logging wrappers can use it to provide the location information to be used by Log4j.
    logging包装类可以使用它来提供Log4j需要的位置信息。
  2. The overhead of capturing location information when using the location method with no parameters is much better than having to calculate the location information when it is needed. Log4j can simply ask for the stack trace entry at a fixed index instead of having to walk the stack trace to determine the calling class. Of course, if the location information will not be used by the layout this will result in slower performance.
    使用无参数的定位方法时捕获位置信息的开销比必须在需要时计算位置信息要好得多。
    Log4j只需在固定索引处请求stack trace entry,而不必遍历堆栈跟踪stack trace以确定调用类。当然,如果布局不使用位置信息(没被用到),则会导致性能降低。

Location Performance

The table below shows some of the results from the FileAppenderBenchmark and FileAppenderWithLocationBenchmark classes in the log4j-perf project when configured to use 4 threads. The results show that lazily including the location information is about 8 times slower than not including location information. While using the withLocation method of LogBuilder is about 3 times faster than lazily calculating the location information it is still about 2.5 times slower than not including location information.
下表显示了配置为使用4个线程时log4j-perf项目中FileAppenderBenchmark和FileAppenderWithLocationBenchmark类的一些结果。
结果表明,懒惰地包含位置信息比不包含位置信息慢了大约8倍。
使用LogBuilder的withLocation方法比延迟计算位置信息快大约3倍,但比不包括位置信息慢大约2.5倍。

The tests were run on a 2018 MacBook Pro with a 2.9 GHz Intel Core i9 processor with 6 cores, 32 GB of memory and 1 TB of SSD storage on Java 11 using Log4j 2.13.0 and Logback 1.2.3. 测试电脑配置信息,感觉像在炫耀。。。手动滑稽脸。

Location Performance
在这里插入图片描述
(这边)

Test Print Location Info No Location Info Printed
Log4j2 File 191,509.724 ± 11339.978 ops/s 1,407,329.130 ± 22595.997 ops/s
Log4j2 Log Builder withLocation() 469,200.684 ± 50025.985 ops/s 577,127.463 ± 11464.342 ops/s
Logback File 159,116.538 ± 1884.969 ops/s 1,240,438.384 ± 76619.873 ops/s

As expected, when using LogBuilder with a call to the withLocation() method logging is much faster when location information is used in the output but significantly slower when it is not.
不出所料,当使用LogBuilder调用withLocation()方法时,在输出中使用位置信息时,日志记录要快得多,而在没有使用位置信息时,记录要慢得多。
(注意,这边柱状越短越快)

由以上柱状图和数据,我们可以得出大致得出3个结论:

  • 记录location比不记录要快。但是withLocation()方法不记录location时要比Logback file 和 log4j2 file的都快很多。——不记录选logBuilder.withLocation()
  • 记录并打印location时,使用withLocation()的速度要比Logback file 和 log4j2 file记录location的情况都要差。——记录时选Log4j2 file
  • 记录location时,log4j2 file 和 logback file的性能差异可以忽略不计。

**综上可知,我们选用Log4j2作为日志框架,可以获得更好的性能;

  • 在不记录时,选用logBuilder的withLocation()方法;
  • 在记录location时,使用log4j2 file的模式。

Note: Running the tests at various times provides varying results. Although some results have been as much as 10% higher all results are generally affected similarly so the comparisons between them stay the same.
注意:在不同时间运行测试会产生不同的结果。
尽管某些结果要高出10%,但所有结果通常都受到类似的影响,因此它们之间的比较保持不变。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章