Java混亂的日志體系(logback)(轉)


作為一名 Java 程序員,日常開發工作中肯定會接觸日志系統,但是眾多的框架,包括 Log4j、Log4j2、Logback、Slf4j、Apache Common logging 等等,引用的 maven 依賴眾多,到底可以去掉哪些,一行 LoggerFactory.getLogger(LogbackTest.class) 后做了哪些工作,怎么去找的配置文件,這些還是有很多細節可以去研究的。

一、困擾的疑惑

目前的日志框架有 jdk 自帶的 logging,log4j1、log4j2、logback ,這些框架都自己定制了日志 API ,並且有相應的實現;目前用於實現日志統一的框架 Apache commons-logging、slf4j ,遵循「面向接口編程」的原則,這兩大框架可以讓用戶在程序運行期間去選擇具體的日志實現系統(log4j1\log4j2\logback等)來記錄日志,是統一抽象出來的一些接口。

這些日志系統涉及到的繁雜的各種集成 jar 包,如下:

  • log4j、log4j-api、log4j-core
  • log4j-1.2-api、log4j-jcl、log4j-slf4j-impl、log4j-jul
  • logback-core、logback-classic、logback-access
  • commons-logging
  • slf4j-api、slf4j-log4j12、slf4j-simple、jcl-over-slf4j、slf4j-jdk14、log4j-over-slf4j、slf4j-jcl

log4j Apache 的一個開放源代碼項目,通過使用Log4j,我們可以控制日志信息輸送的目的地是控制台、文件、GUI組件、甚至是套接口服務 器、NT的事件記錄器、UNIX Syslog守護進程等;用戶也可以控制每一條日志的輸出格式;通過定義每一條日志信息的級別,用戶能夠更加細致地控制日志的生成過程。這些可以通過一個 配置文件來靈活地進行配置,而不需要修改程序代碼。最新的目前版本為log4j 1.2,maven 依賴如下:

<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>

Logback Logback 是由 log4j 創始人設計的又一個開源日記組件,Logback 當前分成三個模塊:logback-core,logback- classic和logback-access。logback-core是其它兩個模塊的基礎模塊,logback-classic是log4j的一個 改良版本。此外logback-classic 完整實現 SLF4J API 使你可以很方便地更換成其它日記系統如log4j或JDK14 Logging。logback-access訪問模塊與Servlet容器集成提供通過Http來訪問日記的功能。maven 最新依賴如下:

<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.6</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.18</version>
</dependency>

更快的執行速度Logback 作為一個通用可靠、快速靈活的日志框架,將作為 Log4j 的替代和 SLF4J 組成新的日志系統的完整實現。Logback 聲稱具有極佳的性能,“ 某些關鍵操作,比如判定是否記錄一條日志語句的操作,其性能得到了顯著的提高。這個操作在LogBack中需要3納秒,而在Log4J中則需要30納秒。 LogBack 創建記錄器(logger)的速度也更快:13微秒,而在Log4J中需要23微秒。更重要的是,它獲取已存在的記錄器只需94納秒,而 Log4J需要2234納秒,時間減少到了1/23。跟JUL相比的性能提高也是顯著的”。另外,Logback的所有文檔是全面免費提供的,不象Log4J那樣只提供部分免費文檔而需要用戶去購買付費文檔。具體包括:

  • 更充分的測試
  • logback-classic 非常自然的實現了SLF4J
  • 使用XML配置文件或者Groovy
  • 自動重新載入配置文件
  • 優雅地從I/O錯誤中恢復
  • 自動清除舊的日志歸檔文件
  • 自動壓縮歸檔日志文件
  • 謹慎模式
  • Lilith
  • 配置文件中的條件處理
  • 更豐富的過濾
  • Logback-access模塊,提供了通過HTTP訪問日志的能力,是logback不可或缺的組成部分

詳細的介紹可以參考:http://www.oschina.net/translate/reasons-to-prefer-logbak-over-log4j

越來越多的開源項目依賴 Logback:

SLF4J 簡單日記門面(Facade) SLF4J 是為各種 loging APIs 提供一個簡單統一的接口,從而使得最終用戶能夠在部署的時候配置自己希望的loging APIs實現。 Logging API實現既可以選擇直接實現SLF4J接的loging APIs如: NLOG4J、SimpleLogger。也可以通過SLF4J提供的API實現來開發相應的適配器如Log4jLoggerAdapter、JDK14LoggerAdapter。

Apache Common-Logging 目前廣泛使用的Java日志門面庫。通過動態查找的機制,在程序運行時自動找出真正使用的日志庫。但由於它使用了ClassLoader尋找和載入底層的日志庫, 導致了象OSGI這樣的框架無法正常工作,由於其不同的插件使用自己的ClassLoader。 OSGI的這種機制保證了插件互相獨立,然而確使Apache Common-Logging無法工作。

SLF4J 庫類似於 Apache Common-Logging。但是,他在編譯時靜態綁定真正的Log庫。使用SLF4J時,如果你需要使用某一種日志實現,那么你必須選擇正確的SLF4J的jar包的集合,如此便可以在OSGI中使用了。另外,SLF4J 支持參數化的log字符串,避免了之前為了減少字符串拼接的性能損耗而不得不寫的if(logger.isDebugEnable()),現在你可以直接寫:logger.debug(“current user is: {}”, user)。拼裝消息被推遲到了它能夠確定是不是要顯示這條消息的時候,但是獲取參數的代價並沒有幸免。同時,日志中的參數若超過三個,則需要將參數以數組的形式傳入,如: 

Object[] params = {value1, value2, value3};
logger.debug(“first value: {}, second value: {} and third value: {}.”, params);

二、how to use

現在,Hibernate、Jetty、Spring-OSGi、Wicket和MINA等越來越多的開源項目都已經遷移到了SLF4J,由此可見SLF4J的影響力不可忽視。

介紹完這些日志框架后,那么這些東西怎么用,之間的依賴是什么樣子的,還有啟動初始化的過程究竟干了什么,怎么找到相應的實現類及配置的?

這四篇文章是我目前在互聯網上面發現的寫的最詳細的介紹,請參考:

  1. jdk-logging、log4j、logback日志介紹及原理 三個日志系統的實現機制介紹
  2. commons-logging與jdk-logging、log4j1、log4j2、logback的集成原理 Apache Commons-logging 通用日志框架與日志系統的機制介紹
  3. SLF4J 與 jdk-logging、log4j1、log4j2、logback的集成原理 SLF4J 通用日志框架與具體日志實現系統的機制機制介紹,包括依賴的jar包,jar沖突處理等;
  4. slf4j、jcl、jul、log4j1、log4j2、logback大總結 各個組件的jar包以及目前系統日志需要切換實現方式的方法,推薦閱讀。
<!-- ================================================= -->
<!-- 日志及相關依賴(用slf4j+logback代替jcl+log4j) -->
<!-- ================================================= -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
</dependency>
<!-- 強制使用 logback的綁定 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.3</version>
</dependency>
<!-- 強制使用 logback的綁定,這里去除對log4j 的綁定 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>99.0-does-not-exist</version>
</dependency>
<!-- slf4j 的橋接器,將第三方類庫對 log4j 的調用 delegate 到 slf api 上 -->
<!-- 這個橋接器是自己做的,主要是我們依賴的類庫存在很多硬編碼的引用 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>1.7.14-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.7</version>
</dependency>
<!-- 強制排除 log4j 的依賴,全部 delegate 到 log4j-over-slf4j 上 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>99.0-does-not-exist</version>
</dependency>
<dependency>
<groupId>apache-log4j</groupId>
<artifactId>log4j</artifactId>
<version>999-not-exist</version>
</dependency>
<!-- slf logback 配置結束 -->

三、結束

通過上述閱讀,對「混亂的 java 日志體系」應該有了較清楚的理解,但是真的存在項目需要切換日志系統的情況嗎?根據我的理解,很多當你的系統越來越龐大,越來越復雜需要系統重構,解決性能的時候,可以考慮升級你當前的日志配置。如果你是新啟用的項目,直接考慮使用Logback + SLF4j 即可。

參考資料

 

參考:

http://www.ixirong.com/2016/03/13/intro-to-java-log/(以上內容轉自此篇文章)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM