0.整體介紹
日誌體系由三部分組成html
所在的位置,以下圖所示:java
1.日誌實現框架
- log4j 最普遍應用的日誌框架,成爲事實上的標準
- jul(java.util.logging) jdk1.4加入,爲了對抗log4j,效率靈活性較差使用較少
- logback 基於slf4j-api接口實現,性能高於log4j
- log4j2 重寫了log4j,性能高於log4j,logback
- 其餘
注:log4j、logback、log4j2是同一個做者Ceki Gülcügit
2.日誌門面接口JCL和SLF4J
上面介紹了四種日誌框架,到底用哪一個日誌框架,如今普遍應用的仍是log4j,若是負載較高能夠考慮使用logback和log4j2.spring
可是若是兩個系統相互依賴,用的不一樣的日誌框架,難道須要依賴兩個日誌框架麼?api
Apache和log4j的做者提供兩種接口層面的彙總框架
- JCL(commons-logging)
- SLF4J(simple log facade for java)兩個日誌框架的門面。
提供了統一的日誌抽象接口,適配和轉接了各類日誌框架,使用者只用調用抽象層統一的接口就好了。應用層不直接依賴實際的日誌實現。性能
可是,問題又來了,怎麼使用呢?日誌
- 問題一:個人項目中準備使用SLF4J做爲接口層面統一,使用logback 做爲日誌實現框架,可是我依賴了一些開源框架使用了log4j,或者JCL(commons-logging),那麼怎麼彙總?
- 個人項目中已經使用了log4j,可是依賴了一些開源框架使用了SLF4J,那麼怎麼轉接SLF4J的實現到log4j呢?
這裏拿SLF4J舉例,JCL(commons-logging)一樣適合場景。htm
3.橋接
問題一,先看一幅圖接口
- 項目中打算使用SLF4J做爲接口層,使用logback做爲實現層
- 項目依賴的開源框架使用了Commons-logging,log4j,juc日誌框架
- 使用jcl-over-slf4j橋接commons-logging
- 使用log4j-over-slf4j橋接log4j
- 使用jul-to-slf4j橋接jul(java.util.logging)
那麼什麼是橋接?
橋接的原理是把對應的門面日誌接口從新實現了一遍,包名、類名、接口都同樣,只是具體實現它委託給SLF4J了。
經過一系列橋接,它們把已存在的日誌門面適配到SLF4J(jul-to-slf4j)。或者仿效已存在的日誌門面或者實現(jcl-over-slf4j,log4j-over-slf4j,jul-to-slf4j)。
總結:
- 好比咱們項目中依賴了spring-core,由於它原生依賴commons-logging,因此須要用jcl-over-slf4j橋接包來代替commons-logging把具體實現委託給slf4j
- 項目中要排除掉commons-logging
- 再依賴jcl-over-slf4j
- jcl-over-slf4j和commons-logging擁有相同的包名、類名、接口,從而達到橋接的效果
4.綁定
再看問題二,再來一幅圖
- 項目中打算使用SLF4J做爲接口層,使用log4j做爲實現層(log4j並無實現SLF4J接口)
- 項目依賴的開源框架使用了Commons-logging,juc日誌框架
- 使用jcl-over-slf4j橋接commons-logging
- 使用jul-to-slf4j橋接jul(java.util.logging)
- slf4j-api綁定到slf4j-log412。基於一個已存在的日誌框架來實現了SLF4J API
那麼什麼是綁定?
綁定的原理是由於slf4j-api中的LogFactory經過StaticLoggerBinder.getSingleton()獲取具體實現logger,一個綁定包實現了org/slf4j/impl/StaticLoggerBinder.class,因此它們在編譯時刻就綁定在一塊兒,而綁定包中的StaticLoggerBinder類會綁定對應的實現。這部分看看源碼就一目瞭然了。
5.總結&實現包附錄
經過橋接和綁定就能夠解決上述的問題。日誌推薦使用作法是,使用SLF4J+logback,若是依賴了其餘開源項目致使日誌混亂,可使用橋接的方式進行解決。
下面附錄一下SLF4J橋接和綁定的包
SLF4J橋接
- jul-to-slf4j:jdk-logging到slf4j的橋接
- log4j-over-slf4j:log4j1到slf4j的橋接
- jcl-over-slf4j:commons-logging到slf4j的橋接
SLF4J綁定
- slf4j-jdk14:slf4j到jdk-logging的綁定
- slf4j-log4j12:slf4j到log4j1的綁定
- log4j-slf4j-impl:slf4j到log4j2的綁定
- logback-classic:slf4j到logback的綁定
- slf4j-jcl:slf4j到commons-logging的綁定
參考文章