Q 業務系統在作發佈前檢查工做時,發現一臺單機的主日誌沒有打印,而其餘生產機器的日誌表現則是正常的。api
經過 greys 觀察主 service 的業務入口,發現該機器線上流量的請求接受、邏輯處理、結果反饋均正常。排查範圍就聚焦在 log jar 配置上。spa
研究了一下 slf4j-log4j12 實現綁定的原理——簡單來講,日誌輸出到單機本地,須要如下 3 類 jar 包相互配合:日誌
具體到代碼實現上,就是經過 StaticLoggerBinder.getSingleton ( ) 方法返回的單例,實現包的綁定 ——blog
qjt 程序中,同時存在着兩類綁定包:log4j-slf4j-impl-2.7.jar 和 slf4j-log4j12-1.7.2.jar。這實際是一種意義上的日誌綁定包衝突 —— 選定哪一個包,取決於 ClassLoader 先加載哪一個,具備必定的隨機性。接口
核心:slf4j-log4j12 意指 slf4j 底層橋接到 log4j;log4j-slf4j-impl 意指 log4j 底層橋接到 slf4j。經過機器本地 lib 庫也能夠看到,qjt 用的 facade 是 log4j。因此若是 classloader 先加載了 slf4j-log4j12 的話,就會沒法打印日誌 —— 由於 log4j 找不到具體的橋接實現了。ip
再來看一下 slf4j-log4j12-empty_version.jar 是什麼東東。經過觀察它的包結構,能夠看到實際上是 slf4j 綁定包的空實現,由此排掉了其餘 jar 包引入的 slf4j-log4j12 實現。ssl
敘述到此,能夠發現正是 ClassLoader 隨機加載兩類綁定包的不一樣,從而致使了日誌打印表現的不一樣。爲了不該狀況,強烈建議各位同窗排查是否存在綁定包的衝突。部署