2015第30周四Java日誌組件

來源:互聯網
上載者:User

標籤:

Java 日誌 API

從功能上來說,日誌 API 本身所需求的功能非常簡單,只需要能夠記錄一段文本即可。API 的使用者在需要進行記錄時,根據當前的上下文資訊構造出相應的文本資訊,調用 API 完成記錄。一般來說,日誌 API 由下面幾個部分組成:

  • 記錄器(Logger):日誌 API 的使用者通過記錄器來發出日誌記錄請求,並提供日誌的內容。在記錄日誌時,需要指定日誌的嚴重性層級。當 程式中需要記錄日誌時,首先需要擷取一個日誌記錄器對象。一般的日誌記錄 API 都提供相應的Factory 方法來建立記錄器對象。每個記錄器對象都是有名稱的。一般的做法是使用當前的 Java 類的名稱或所在包的名稱作為記錄器對象的名稱。
  • 格式化器(Formatter):對記錄器所記錄的文本進行格式化,並添加額外的中繼資料。實際記錄的日誌中除了使用記錄器對象時提供的訊息之外,還包括一些中繼資料。這些中繼資料由日誌紀錄架構來提供。常用的資訊包括記錄器的名稱、時間戳記、線程名等。格式化器用來確定所有這些資訊在日誌記錄中的展示方式。不同的日誌記錄實現提供各自預設的格式化方式和自訂支援。
  • 處理器(Handler):把經過格式化之後的日誌記錄輸出到不同的地方。常見的日誌輸出目標包括控制台、檔案和資料庫等。
Java 日誌封裝 API

封裝庫中一開始以 Apache Commons Logging 架構最為流行,現在比較流行的是 SLF4J。這樣封裝庫的 API 都比較簡單,只是在日誌記錄庫的 API 基礎上做了一層簡單的封裝,屏蔽不同實現之間的區別。由於日誌記錄實現所提供的 API 大致上比較相似,封裝庫的作用更多的是達到文法上的一致性。

在 Apache Commons Logging 庫中,核心的 API 是 org.apache.commons.logging.LogFactory 類和 org.apache.commons.logging.Log 介面。LogFactory 類提供了Factory 方法用來建立 Log 介面的實現對象。比如 LogFactory.getLog 可以根據 Java 類或名稱來建立 Log 介面的實現對象。Log 介面中為 6 個不同的嚴重性層級分別定義了一組方法。比如對 DEBUG 層級,定義了 isDebugEnabled()、debug(Object message) 和 debug(Object message, Throwable t) 三個方法。從這個層次來說,Log 介面簡化了對於日誌記錄器的使用。

SLF4J 庫的使用方式與 Apache Commons Logging 庫比較類似。SLF4J 庫中核心的 API 是提供Factory 方法的 org.slf4j.LoggerFactory 類和記錄日誌的 org.slf4j.Logger 介面。通過 LoggerFactory 類的 getLogger 方法來擷取日誌記錄器對象。與 Apache Commons Logging 庫中的 Log 介面類似,Logger 介面中的方法也是按照不同的嚴重性層級來進行分組的。Logger 介面中有同樣 isDebugEnabled 方法。不過 Logger 介面中發出日誌記錄請求的 debug 等方法使用 String 類型來表示訊息,同時可以使用包含參數的訊息。

slf4j 與 common-logging 比較 common-logging通過動態尋找的機制,在程式運行時自動找出真正使用的日誌庫。由於它使用了ClassLoader尋找和載入底層的日誌庫, 導致了象OSGI這樣的架構無法正常工作,因為OSGI的不同的外掛程式使用自己的ClassLoader。 OSGI的這種機制保證了外掛程式互相獨立,然而卻使Apache Common-Logging無法工作。
slf4j在編譯時間靜態繫結真正的Log庫,因此可以再OSGI中使用。另外,SLF4J 支援參數化的log字串,避免了之前為了減少字串拼接的效能損耗而不得不寫的if(logger.isDebugEnable()),現在你可以直接寫:logger.debug(“current user is: {}”, user)。拼裝訊息被延遲到了它能夠確定是不是要顯示這條訊息的時候,但是擷取參數的代價並沒有倖免。  日誌架構實現Log4jApache的一個開放原始碼項目,通過使用Log4j,我們可以控制日誌資訊輸送的目的地是控制台、檔案、GUI組件、甚至是套介面服務 器、NT的事件記錄器、UNIX Syslog守護進程等;使用者也可以控制每一條日誌的輸出格式;通過定義每一條日誌資訊的層級,使用者能夠更加細緻地控制日誌的產生過程。這些可以通過一個 設定檔來靈活地進行配置,而不需要修改程式碼。

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

Log4j 與 LogBack 比較LogBack作為一個通用可靠、快速靈活的日誌架構,將作為Log4j的替代和SLF4J組成新的日誌系統的完整實現。LOGBack聲稱具有極佳的效能,“ 某些關鍵操作,比如判定是否記錄一條日誌語句的操作,其效能得到了顯著的提高。這個操作在LogBack中需要3納秒,而在Log4J中則需要30納秒。 LogBack建立記錄器(logger)的速度也更快:13微秒,而在Log4J中需要23微秒。更重要的是,它擷取已存在的記錄器只需94納秒,而 Log4J需要2234納秒,時間減少到了1/23。跟JUL相比的效能提高也是顯著的”。 另外,LOGBack的所有文檔是全面免費提供的,不象Log4J那樣只提供部分免費文檔而需要使用者去購買付費文檔。   總結介面:將所有日誌實現適配到了一起,用統一的介面調用。 
實現:目前主流的日誌實現 
舊日誌到slf4j的適配器:如果使用了slf4j,但是只想用一種實現,想把log4j的日誌體系也從logback輸出,這個是很有用的。 
slf4j到實現的適配器:如果想制定slf4j的具體實現,需要這些包。 

slf4J與舊日誌架構的關係 
slf4j等於commons-logging,是各種日誌實現的通用入口,會根據classpath中存在下面哪一個Jar來決定具體的日誌實現庫。 
logback-classic(預設的logback實現) 
slf4j-jcl.jar(apache commons logging) 
slf4j-logj12.jar(log4j 1.2.4) 
slf4j-jdk14(java.util.logging) 
將所有使用舊式日誌API的第三方類庫或舊代碼的日誌調用轉到slfj 
jcl-over-slf4j.jar/jcl104-over-slf4j:apache commons logging 1.1.1/1.0.4,直接替換即可。 
log4j-over-slf4j.jar:log4j,直接替換即可。 
jul-to-slf4j:jdk logging,需要在程式開始時調用SLF4JBridgeHandler.install()來註冊listener參考JulOverSlf4jProcessor,可在applicationContext.xml中定義該bean來實現初始化。注意原有的log4j.properites將失效,logback網站上提供轉換器,支援從log4j.properties 轉換到logback.xml 。  日誌組件相關曆史Java 界裡有許多實現日誌功能的工具,最早得到廣泛使用的是 log4j,許多應用程式的日誌部分都交給了 log4j,不過作為組件開發人員,他們希望自己的組件不要緊緊依賴某一個工具,畢竟在同一個時候還有很多其他很多日誌工具,假如一個應用程式用到了兩個組件,恰好兩個組件使用不同的日誌工具,那麼應用程式就會有兩份日誌輸出了。

為瞭解決這個問題,Apache Commons Logging (之前叫 Jakarta Commons Logging,JCL)粉墨登場,JCL 只提供 log 介面,具體的實現則在運行時動態尋找。這樣一來組件開發人員只需要針對 JCL 介面開發,而調用組件的應用程式則可以在運行時搭配自己喜好的日誌實踐工具。

所以即使到現在你仍會看到很多程式應用 JCL + log4j 這種搭配,不過當程式規模越來越龐大時,JCL的動態綁定並不是總能成功,具體原因大家可以 Google 一下,這裡就不再贅述了。解決方案之一就是在程式部署時靜態繫結指定的日誌工具,這就是 SLF4J 產生的原因。

跟 JCL 一樣,SLF4J 也是只提供 log 介面,具體的實現是在打包應用程式時所放入的綁定器(名字為 slf4j-XXX-version.jar)來決定,XXX 可以是 log4j12, jdk14, jcl, nop 等,他們實現了跟具體日誌工具(比如 log4j)的綁定及代理工作。舉個例子:如果一個程式希望用 log4j 日誌工具,那麼程式只需針對 slf4j-api 介面編程,然後在打包時再放入 slf4j-log4j12-version.jar 和 log4j.jar 就可以了。

現在還有一個問題,假如你正在開發應用程式所調用的組件當中已經使用了 JCL 的,還有一些組建可能直接調用了 java.util.logging,這時你需要一個橋接器(名字為 XXX-over-slf4j.jar)把他們的日誌輸出重新導向到 SLF4J,所謂的橋接器就是一個假的日誌實現工具,比如當你把 jcl-over-slf4j.jar 放到 CLASS_PATH 時,即使某個組件原本是通過 JCL 輸出日誌的,現在卻會被 jcl-over-slf4j “騙到”SLF4J 裡,然後 SLF4J 又會根據綁定器把日誌交給具體的日誌實現工具。過程如下

Component
|
| log to Apache Commons Logging
V
jcl-over-slf4j.jar --- (redirect) ---> SLF4j ---> slf4j-log4j12-version.jar ---> log4j.jar ---> 輸出日誌

看到上面的流程圖可能會發現一個有趣的問題,假如在 CLASS_PATH 裡同時放置 log4j-over-slf4j.jar 和 slf4j-log4j12-version.jar 會發生什麼情況呢?沒錯,日誌會被踢來踢去,最終進入死迴圈。

所以使用 SLF4J 的比較典型搭配就是把 slf4j-api、JCL 橋接器、java.util.logging(JUL)橋接器、log4j 綁定器、log4j 這5個 jar 放置在 CLASS_PATH 裡。

不過並不是所有APP容器都是使用 log4j 的,比如 Google AppEngine 它使用的是 java.util.logging(JUL),這時應用 SLF4J 的搭配就變成 slf4j-api、JCL橋接器、logj4橋接器、JUL綁定器這4個 jar 放置在 WEB-INF/lib 裡。 http://blog.jobbole.com/51155/http://phl.iteye.com/blog/2021461http://blog.csdn.net/yycdaizi/article/details/8276265

2015第30周四Java日誌組件

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.