記一次項目上線后Log4j2不輸出日志的坑


    公司項目采用了Log4j2來輸出日志,在開發環境和測試環境下均可以輸出日志,但在生成環境就沒有日志輸出。開始毫無頭緒,后來通過不斷的排查,終於解決了這個問題。在此記錄下該問題的解決過程,便於后續查閱。

一、發現問題

     開發環境打印日志但生產環境不打印日志這個問題比較棘手。一直找不到原因,后面突然想到在啟動的時候打印信息肯定會有所不同。通過在 2個環境啟動同一個項目的控制台打印信息對比有了以下的發現:
(1) 出現了 SL4J 的警告信息,都是提示包沖突
               Multiple bindings were found on the class path
(2) 但是仔細觀察發現了 加載這兩個沖突的jar包的順序不同 ,具體見下圖:

    ①開發環境日志沖突jar包加載順序圖

        防止圖失效,我把文字復制過來了
SLF4J:Class path contains mutiple SLF4J bindings
SLF4J:Found binding in[jar:file:/WEB-INF/lib/log4j-slf4j-impl-2.6.6.jar!/org/slf4j/impl/StaticLoggerBider.class]
SLF4J:Found binding in[jar:file:/WEB-INF/lib/slf4j-log4j12-1.7.22.jar!/org/slf4j/impl/StaticLoggerBider.class]

    

    ②生產環境日志沖突jar包加載順序圖

        防止圖失效,我把文字復制過來了

SLF4J:Class path contains mutiple SLF4J bindings
SLF4J:Found binding in[jar:file:/WEB-INF/lib/slf4j-log4j12-1.7.22.jar!/org/slf4j/impl/StaticLoggerBider.class]
SLF4J:Found binding in[jar:file:/WEB-INF/lib/log4j-slf4j-impl-2.6.6.jar!/org/slf4j/impl/StaticLoggerBider.class]

二、分析

  • 在開發環境,先加載的是 log4j-slf4j-impl ,后加載的是slf4j-log4j12。而生產環境, 先加載的是 slf4j-log4j12 ,后加載的是log4j-slf4j-impl
  • 通過查閱官方資料發現slf4j在綁定時,如果有多個可以綁定的包, SLF4J選擇綁定的方式由JVM確定,並且出於所有實際目的應該被認為是隨機的
  • 但是 ,經過我12次在slf4j源碼打斷點測試發現slf4j優先綁定先加載的jar包。所以在開發環境slf4j綁定的是log4j-slf4j-impl這個jar包,而在生產環境中綁定的是slf4j-log4j12這個jar包。
  • 通過查閱log4j2官方資料可知,slf4j集成log4j2時需要的橋接包是 log4j-slf4j-impl 開發環境中slf4j綁定是正確的,因此可以打印日志 。而生產環境中slf4j綁定的jar包是slf4j-log4j12。所以生產環境輸出不了日志。產生這個問題的根本原因是lib里面有多個了slf4j可綁定的jar包。

三、解決方案

     由於是slf4j綁定jar包錯誤而導致打印不了日志。所以我們必須要把這個slf4j-log4j12.jar包排除干凈。這個包主要來源有:
1framework-logger(公司自己封裝的框架)
2zkclient
3zookeeper
    排除完jar包后,本地進行打包。打包完成后,必須要檢查一遍,看一下生成的打包文件的lib文件夾下是否還存在slf4j-log4j12.jar。如果有,應該是jar包沒排除干凈。可以通過maven命令查看依賴樹,看看是那個依賴把這個jar給傳遞進來的。命令為:dependency:tree

四、小結

(1)使用SLF4j+Log4j2時使用的橋接包是log4j-slf4j-impl
(2)當有多個SLF4j的橋接包時,一定要排除不需要的包
(2)項目啟動時控制台輸出的信息很重要,耐心觀察啟動日志可以解決很多問題








免責聲明!

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



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