SLF4J的使用和Log4j的配置
完整用戶手冊請異步:SLF4J 使用手冊
SLF4J是Simple Logging Facade for Java的簡寫,即Java簡單日誌門面,用來服務於各類各樣的日誌框架,好比java.util.logging、logback和log4j。SLF4J容許最終用戶在部署時集成本身想要的日誌框架。
須要注意的是,你的應用啓用SLF4J意味着須要一個額外的依賴:slf4j-api-1.7.19.jar。
從1.6.0開始:若是在class path沒有找到綁定,SLF4J將默認一個無操做的實現。
從1.7.0開始:Logger接口中的打印方法如今提供variants取代了Object[]用來接收可變長參數。這個改變意味着SLF4J須要JDK 1.5或更高的版本。Java編譯器在底層把方法中的可變參數部分轉換成Object[]。所以,編譯器生成的Logger接口在1.7.x版本中和它對應的的1.6.x版本中是沒有區別的。所以SLF4J得1.7.x版本和1.6.x版本是 徹底兼容的。
從1.7.5開始:日誌的檢索時間有了一個顯著的改善,鑑於這個改善,很是鼓勵用戶遷移到SLF4J 1.7.5或更高的版本。
從1.7.9開始: 經過設置 slf4j.detectLoggerNameMismatch 系統屬性爲true,SLF4J能自動的 spot incorrectly named loggers.html
按照慣例,下面的示例說明最簡單的方法使用SLF4J輸出」hello world「。他首先獲取一個名爲」HelloWorld「的記錄器,這個記錄器用來記錄」HelloWorld「。java
public class HelloWorld { public static void main(String[] args) { Logger logger = LoggerFactory.getLogger(HelloWorld.class); logger.info("Hello World"); } }
編譯運行HelloWorld,控制檯將有一下輸出:編程
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
這個警告會被打印是由於在class path下沒有找到綁定的slf4j。api
一旦你添加一個綁定在你的class path下,這個警告將會消失。假設你添加了 slf4j-simple-1.7.19.jar,你的class path包含:app
編譯並運行HelloWorld程序,如今在控制檯會有下列輸出:框架
0 [main] INFO HelloWorld - Hello World
下面的示例代碼代表了SLF4J的典型使用模式。注意15行」{}「的使用,查看 「What is the fastest way of logging?」獲取更多細節。異步
public class Wombat { final Logger logger = LoggerFactory.getLogger(Wombat.class); Integer t; Integer oldT; public void setTemperature(Integer temperature) { oldT = t; t = temperature; logger.debug("Temperature set to {}. Old temperature was {}.", t, oldT); if(temperature.intValue() > 50) { logger.info("Temperature has risen above 50 degrees."); } } public static void main(String[] args) { new Wombat().setTemperature(60); } }
在部署時綁定一個日誌框架
像在以前提到過的,SLF4J支持各類各樣的日誌框架。SLF4J的發行版附帶的幾個jar被稱爲」 SLF4J bindings「 ,每一個綁定都對應一個支持的框架。
切換日誌框架,只須要替換class path中的slf4j綁定。好比說,從 java.util.logging切換到 log4j,僅僅把 slf4j-jdk14-1.7.19.jar替換成 slf4j-log4j12-1.7.19.jar。
SLF4J不依賴於特定的類加載機制。事實上,每一個SLF4J綁定在編譯時硬鏈接來使用一個指定的日誌框架。好比說, slf4j-log4j12-1.7.19.jar在編譯時綁定使用log4j。在你的代碼中,除 slf4j-api-1.7.19.jar以外,只能有一個你選擇的綁定 到正確的class path 路徑上。不要在class path 放置多個綁定。下面是一個圖表來講明通常的想法。
測試
爲了不給他們的終端用戶強加一個日誌框架 ,一些組件和庫的做者可能會針對SLF4J接口進行編程。所以,終端用戶在部署時能夠經過在classpath插入對應的slf4j綁定來選擇他們指望的日誌框架。而且,能夠把在classpath存在的綁定替 換到另一個,而後重啓應用,從而達到切換日誌框架的目的,這個方法被證實是很是簡單和健壯的。網站
SLF4J的1.6.0版本,若是在class path 沒有發現綁定,slf4j-api將默認一個無操做的實現來忽略全部的日誌請求。所以,SLF4J從1.6.0版開始發出一個缺乏綁定的警告,而後丟棄全部的打印日誌請求,而不是拋出 NoClassDefFoundError異 常由於缺乏 org.slf4j.impl.StaticLoggerBinder 類 。好比說: Wombat 一些基礎框架依賴於SLF4J來打印日誌。爲了不強加一個日誌框架給終端用戶,Wombat 包含 slf4j-api.jar可是沒有綁定。在class path 沒有SLF4J綁定的情 況下,Wombat的發行版依然能開箱即用,不須要終端用戶下載從SLF4J網站下載一個綁定。僅僅當終端用戶開啓日誌的時候,將須要安裝他選擇的日誌框架對應的SLF4J綁定。spa
基本準則:內置的組件好比庫和框架不該該聲明任何SLF4J的依賴,可是依賴於SLF4J-api。當一個庫在一個指定的綁定聲明一個傳遞依賴,這個強加於終端用戶的綁定否認了SLF4J的目的。注意,在綁定上聲明一個非傳遞性的依賴,好比說 對測試,不影響終端用戶。
內嵌組件中SLF4J的使用也在FAQ中進行討論。有關係的章節: logging configuration dependency reduction testing
鑑於Maven的傳遞依賴規則,對於」regular「項目(不是庫和框架),日誌依賴聲明 能夠經過一個單獨的依賴聲明來實現。
LOG4J:若是你但願使用log4j做爲底層的日誌框架,你須要作的全部事情就是聲明」 org.slf4j:slf4j-log4j12「依賴到你的pom.xml文件中。除了 slf4j-log4j12-1.7.19.jar以外,它將拉取 slf4j-api-1.7.19.jar和 log4j-1.2.17.jar到你的項目 中。注意,顯示地聲明一個依賴 log4j-1.2.17.jar或 slf4j-api-1.7.19.jar 沒有錯。而且可能須要強加一個正確的版本
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.19</version> </dependency>
一般,一個給定的項目依賴於各類各樣的組件,這些組件依賴的日誌API不是SLF4J。一個項目依賴於一個JCL、java.util.logging、log4j和SLF4J是很常見的。而後經過一個單獨的方式來統一日誌變得讓人滿意。SLF4J經過提供對JCL、
java.util.logging、和slf4j的橋接模塊來知足這個普通的用例。更詳細的內容,請參考 Bridging legacy APIs.
「Mapped Diagnostic Context」本質上是日誌框架包含的一個map,應用程序代碼提供了key-value對,這個鍵值對能被日誌框架插入到日誌信息中去。MDC數據在過濾信息或觸發某些操做時是很是有用的。
SLF4J支持MDC,若是一個底層的日誌框架提供了MDC功能,SLF4J將委託給底層日誌框架的MDC。注意,如今僅僅只有log4j和logback提供了MDC功能。若是底層日誌框架不支持MDC,好比說java.util.loggin,SLF4J將存儲MDC數 據,可是裏面的數據須要用戶經過代碼來獲取。
所以,做爲一個SLF4J使用者,能利用當 log4j和logback存在時的 MDC信息,可是不能強迫用戶依賴這些日誌框架。
關於MDC的更多信息參見 chapter on MDC