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%,但所有結果通常都受到類似的影響,因此它們之間的比較保持不變。

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