Java日志概述

今天看到了一篇對Java日志系統講解很不錯的文章,所以做個學習記錄,如有侵權請聯系刪除

概述

???????Java的日志系統非常豐富,常用的有log4j、JUL、logback等等,隨著日志系統的發展出現了日志框架commons-logging、slf4j

發展史

???????日志最早出現的是apache開源社區的log4j,是應用最為廣泛的日志工具,然而sun公司在JDK1.4中增加了JUL日志實現企圖對抗log4j,同時斷斷續續也出現了其他的日志工具,這就造成了混亂,因為這些日志系統互相沒有關聯,替換和統一變得棘手,想象一下你的應用使用了log4j,然后使用了其他團隊的庫,而他們使用了JUL,那么你的應用就需要使用兩個日志系統了,然后又有第二個庫使用了simplelog,這個時候估計你就會崩潰了...那么如何解決呢?進行抽象,抽象出一個接口層對每個日志實現都適配或者轉接,提供給別人的庫都直接使用抽象層而具體的實現由使用者決定。不錯,開源社區提供了commons-logging抽象,被稱為JCL,JCL確實出色的完成了兼容主流的日志實現(log4j、JUL、simplelog),基本一統江湖,就連大名鼎鼎的spring也是依賴了JCL。然而好景不長,另一個優秀的日志框架slf4j的出現使場面更加混亂,而slf4j的作者(Ceki Gülcü)正是log4j的作者,他覺得JCL不夠優秀所以要搞一套更優雅的出來,于是slf4j誕生了,同時為slf4j實現了一個親兒子——logback。
???????slf4j確實更加優雅,但是之前已有很多代碼庫已經使用了JCL,雖然出現了slf4j與JCL之間的橋接轉換,但是集成的時候依然問題多多,到此本來應該完了,但是Ceki Gülcü覺得還是得回頭拯救下自己的“大阿哥”——log4j,于是log4j2誕生了,同樣log4j2也參與到了slf4j日志體系中,想必將來會更加混亂......

JCL

???????使用JCL一般需要配置一個commons-logging.properties在classpath上,這個文件有一行代碼:

org.apache.commons.logging.LogFactory= org.apache.commons.logging.impl.LogFactoryImpl

???????這個是告訴JCL我們要使用哪個日志實現,JCL會在classpath下去加載對應的日志工廠實現類,具體的日志工廠實現類可以是log4j,也可以是jul等等。用戶主需要依賴JCL的api即可,對日志系統的替換主需要修改一下commons-logging.properties文件切換到對應的日志工廠實現即可,但是我們也可以看到因為JCL是在運行時去加載classpath下的實現類,會有classloader的問題。

slf4j

???????slf4j的設計確實比較優雅,它采用了我們比較熟悉的方式——接口和實現分離,有個純粹的接口層slf4j-api工程,這個里面基本完全定義了日志的接口,所以對于開發者來說只需要是這個即可。
???????有接口就要有實現,比較推崇的實現是logback,logback完全實現了slf4j-api的接口,并且性能是那個也比log4j更好,我們知道log4j的使用比較普遍,所以為了支持這部分用戶是必須的,slf4j-log4j12也實現了slf4j-api,這個算是對log4j的適配器。同樣的道理,對JUL的是配置為slf4j-jdk14。
???????為了讓使用JCL等等其他其他日志系統的用戶可以很簡單的切換到slf4j上來,給出了各種橋接工程,例如:jcl-over-slf4j會把JCL的調用都橋接到slf4j上來(可以看出jcl-over-slf4j的api和JCL是相同的,所以這兩個jar是不能共存的),jul-to-slf4j是把jul的調用橋接到slf4j上,log4j-over-slf4j是把log4j的調用橋接到slf4j,下面用一張圖來表示下這個家族的大致成員(紅線表示沖突)


???????如上圖所示,最上層表示橋接層,中間是接口層,最下層表示具體的實現,可以看出這個圖中所有的jar都是圍繞著slf4j活動的,其中slf4j-jul的jar包名稱是slf4j-jdk14
???????slf4j-api和具體的實現層是怎么綁定的呢?這個其實是在編譯時綁定的,它可以不需要像使用JCL那樣需要配置一下,只需要把slf4j-api和slf4j-log4j放到classpath上,即實現綁定。原理可以下載slf4j-api的源碼查看,這個設計還是很巧妙的,slf4j-api中會去調用StaticLoggerBinder這個類獲取綁定的工廠類,而每個日志實現會在自己的jar中提供這樣一個類,這樣slf4j-api就實現了編譯時綁定實現。但是這樣接口的源碼編譯需要依賴具體的實現了,不太合理吧?這里容易讓人迷惑,因為打開slf4j-api的jar,看不到StaticLoggerBinder,當我們去查看slf4j-api的源碼,在源碼中看到了StaticLoggerBinder這個類,猜想應該是slf4j-api在打包過程中有動作,刪除了自己包中的那個類,結果不出所料,確實是pom中的ant-task給處理了,pom中處理方式如下:

<plugin>  
        <groupId>org.apache.maven.plugins</groupId>  
        <artifactId>maven-antrun-plugin</artifactId>  
        <executions>  
          <execution>  
            <phase>process-classes</phase>  
            <goals>  
             <goal>run</goal>  
            </goals>  
          </execution>  
        </executions>  
        <configuration>  
          <tasks>  
            <echo>Removing slf4j-api's dummy StaticLoggerBinder and StaticMarkerBinder</echo>  
            <delete dir="target/classes/org/slf4j/impl"/>  
          </tasks>  
        </configuration>  
      </plugin>  

???????打出來的slf4j-api的包是"不完整"的,只有找到包含StaticLoggerBinder這個類的包才可以,于是slf4j-log4j和logback-classic都提供了這個類。另外,slf4j-log4j和logback以及slf4j-jdk14是不能同時和slf4j共存的,也就是說只能有一個實現存在,不然啟動會提示有多個綁定。
???????同時這個圖中橋階層和對應的實現jar是不能共存的,比如log4j-over-slf4j和slf4j-log4j,jul-to-slf4j和slf4j-jdk14,這個很好理解,會有死循環,啟動也會報錯。也就是說jar之前有互斥性。
???????當然slf4j也提供了可以把對slf4j的調用橋接到JCL上的工程包——slf4j-jcl,可以看出slf4j的設計者考慮非常周到,想想這樣的情況:遺留系統使用的是JCL+log4j,因為系統功能演進,依賴了其他業務線的庫,恰好那個庫依賴了slf4j-api,并且應用需要關心這個庫的日志,那么就需要轉接日志到JCL上即可。細心的你可能一經發現,slf4j-jcl和jcl-over-slf4j也是互斥的,太多互斥的了.......
???????對于log4j2的加入,也很簡單,和logback是很相似的,如下圖:



紅線依然表示依賴的互斥,當然log4j-slf4j-impl也會和logback-classic、slf4j-log4j、slf4j-jdk14互斥。

常見的問題:

  • slf4j-api和實現版本不對應,尤其是1.6.x和1.5.x不兼容,如果沒有特殊需求,直接升級到最新版本。

  • slf4j的多個實現同時存在,比如slf4j-log4j和logback-classic,排除其中一個即可。

  • log4j和logback不能同時使用?可以同時使用,這兩個并不矛盾,遺留系統可能直接使用了log4j的代碼,并且不能通過log4j-over-slf4j橋接,那么可以讓他繼續使用log4j,這里(http://www.slf4j.org/legacy.html)有詳細的介紹。

  • 該如何選用這些呢?建議在非特殊情況下,都使用slf4j-api+logback,不要直接使用日志實現,性能沒什么影響。對于要提供給別人的類庫,建議使用slf4j-api,使用方可以自由選擇具體的實現,并且建議類庫不要依賴具體的日志實現。對于自己的桌面小應用,可以直接使用log4j,畢竟只是隨便做做。

  • logback因為木有spring提供的啟動listener,所以要自己寫?可以看看這里(https://github.com/qos-ch/logback-extensions),開源社區已經做好了。

  • 日志系統一般不會影響到系統性能,除非你的系統對性能非常苛刻,如果這樣你可以考慮使用Blitz4j(https://github.com/Netflix/blitz4j),這個是Netflix(http://netflix.github.io/)社區對log4j的性能改進版,不過他們依然建議去使用log4j或者logback。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容

  • 歷史 log4j可以當之無愧地說是Java日志框架的元老,1999年發布首個版本,2012年發布最后一個版本,20...
    kelgon閱讀 10,182評論 3 53
  • 對于Java的日志框架,你也許會經常看到這些名詞: Log4j、Log4j2 Logback Slf4j JCL ...
    NoahU閱讀 3,968評論 0 15
  • JAVA日志系統的演變史 我們先看一個故事。項目經理A帶著一幫兄弟開發了一套復雜的企業ERP系統,這個系統一連開發...
    糖寶_閱讀 655評論 0 4
  • log4j, log4j2, slf4j, logback關系 log4j是由Apache開發的一套元老級日志框架...
    rainybowe閱讀 1,669評論 0 4
  • 前言 最近學習開java web服務器開發,開始學習java,處理業務邏輯,但對其中的日志比較好奇,之前沒怎么接觸...
    九風萍舟閱讀 3,309評論 1 6