天天看點

java log4j,Log4j2 還是 Logback?

作者:MYJ2C混淆

日志架構大戰随着 SLF4j 的一統天下而落下帷幕,但 SLF4j 僅僅是接口,實作方面, logback 與 log4j2 仍然難分高下,今天我們就來聊一聊,日志架構實作到底是該選擇 Log4j2 還是 Logback。這篇文章我們将從功能、API 設計、可擴充性、性能四個方面展開讨論。

生态

老牌的 Log4j 憑借着入場早、背靠 Apache 兩大優勢有着不錯的使用者支援,官網文檔也很完善。

新生的 Logback 憑借着 SLF4j 的原生實作以及被 Spring Boot 欽點的日志架構(Spring 也提供了Log4j2 的 starter,切換依賴即可完成更換日志架構,前文講過,此處不再贅述),同樣也擁有着很好的前景。

社群支援方面,Log4j2 作為 Apache 頂級項目,支援度應該是很不錯的,Logback 作為Ceki創業後的産物,也能有很好的保證,二者生态可謂不相上下。

功能

日志的功能我們從使用者的角度可以分為:配置、使用、以及獨有特性。配置檔案方面,Log4j 提供了更多的配置檔案配置方式,Log4j2 支援 properties、YAML、JSON、XML四種,Logback 則支援 XML 與 groovy 兩種方式;

Appender 方面,兩者均支援自定義擴充 Appender ,Log4j2 并且提供了幾乎全部場景的 Appender,檔案、控制台、JDBC、NoSql、MQ、Syslog、Socket、SMTP等,Logback提供 Appender 略少于 Log4j2,提供了檔案、控制台、資料庫、Syslog、Socket、SMTP等,動态化輸出方面,Log4j2 提供了ScriptAppenderSelector,Logback 則提供了 Evaluator 與 SiftingAppender(兩者均可以用于判斷并選擇對應的 Appender);

獨有特性方面,Logback 支援 Receivers, 可以接收其他 Logback 的 Socket Appender 輸出,Logbak 還擁有 logback-access 子產品,可以用來與 Servlet容器(如 Tomcat 和 Jetty)內建,提供 http 通路日志功能;Log4j2 則擁有号稱能夠減少 JVM 垃圾回收停頓時間的 Garbage-free(無垃圾模式),Log4j2 API 支援使用 Java 8 lambda,SLF4j 則在 2.0 版本提供流式(Fluent)API 同時支援 lambda;

java log4j,Log4j2 還是 Logback?

API 設計及可擴充性

如前文所說,SLF4j 則在 2.0 版本提供流式(Fluent)API ,屆時Logback将會原生實作(理論上會比動态轉譯過去要好),而 Log4j2 并沒有提供支援。擴充方面,Logback 采用配置檔案中直接寫對應實作(class="ch.qos.logback.core.rolling.RollingFileAppender")來自定義實作擴充,Log4j2 采用插件機制,無需配置,但比較複雜,個人認為 Logback 反而清晰一些。

性能

性能方面,Log4j2 官網有很好的性能測試報告,結果是 Log4j2 完勝,本着嚴謹的态度,還要自己來測試一下,進行同步和異步輸出檔案測試,測試一分鐘,無預熱,采用檔案滾動模式,gzip壓縮,總計輸出(gzip壓縮後) 700~900 MB 左右,測試版本: # logback 1.2.3,# log4j 2.13.0,# SLf4j 1.7.30,# JDK 1.8.0_232,測試過程中二者都使用了SLF4j 作為 API 輸出日志。

日志輸出格式:

logback:%d{yyyy-MM-dd HH:mm:ss.SSS} %5p [%t] %-40.40logger{39} : %m%n

Log4j2:%d{yyyy-MM-dd HH:mm:ss.SSS} %5p [%t] %-40.40c{1.} : %m%n

測試結果如下:

java log4j,Log4j2 還是 Logback?
java log4j,Log4j2 還是 Logback?

從測試結果來看二者差異并不大,吞吐量表現上,同步輸出在單線程上要好于異步輸出,異步輸出方面,Log4j2 要優于Logback;響應時間表現上,二者無論同步、異步差距都不大,并且都表現為線程越多響應越慢,應該是線程切換和加鎖開銷所緻,值得一提的是,異步輸出時 CPU 使用率會更高一點。

總結

Logback 使用更簡單、Log4j2 功能更強大,如果不是深度使用,兩者并不會有太大差别,并且在使用SLF4j的時候可以無縫切換。個人建議,不必糾結選型,按照偏好選擇即可。