[英]Log4j Commons Logging Bridge ignored
我們的 Web 應用程序在 tomcat 9 容器中運行,並使用Log4j 2.13.3 作為日志系統。
Web 應用程序包括 org.apache.xmlgraphics:fop 2.3,它使用 apache commons-logging (在我們的設置中是 1.2 版,而不是最初在 fop 中使用的 1.0.4 版)。
這種組合已經使用 log4-jcl、Commons Logging Bridge 運行了多年,並且所有 commons-logging 輸出都正確地進入了 log4j 配置的文件中。 配置相當簡單,如this SO answer中所述
然而,沒有明顯的原因,fop 最近開始將其所有(相當冗長的)日志寫入 stderr(即直接寫入 catalina.out)而不是配置的日志文件,但僅限於我們的某些系統。 我們有大約 50 個 tomcat 實例運行基本相同的軟件和相同的系統配置; 其中三分之一仍然正確記錄。
我假設 commons-logging 沒有找到 log4j-jcl 的 org.apache.commons.logging.LogFactory 實現。
使用Configuration status="trace"調試 log4j 不會提供 log4j-jcl 或其他地方的任何失敗提示。
我沒腦子了有什么建議?
回答我自己的問題,以防對其他人有幫助。
我需要在類路徑中添加一個名為commons-logging.properties的文件,其中包含一行:
org.apache.commons.logging.LogFactory=org.apache.logging.log4j.jcl.LogFactoryImpl
感謝 Piotr 關於設置 org.apache.commons.logging.diagnostics.dest 的評論。
顯然,如果未明確指定類,則實際使用的 LogFactory 的實現取決於類加載器加載潛在候選者的(有點隨機)順序。
我的 webapp 一個 maven 依賴項帶來了 sl4f 作為傳遞依賴項,因此在某些系統上選擇了 slf4j 而不是 log4j,但 slf4 沒有有效配置並默認為 STDERR。
雖然您的回答解釋了為什么沒有選擇 Log4j 2.x 作為 JCL 的后端,但有些細節並沒有增加:原始的commons-logging
從不選擇 SLF4j 作為后端(參見源代碼)。 因此,情況必須更加復雜:
commons-logging
通過ServiceLoader
實用程序發現替代的LogFactory
實現。LogFactory
實現: log4j-jcl
和spring-jcl
。 后者是標准commons-logging
庫的完整替代品(即它包含org.apache.commons.logging.LogFactory
本身的副本)並具有一些復雜的后端選擇規則(參見源代碼),在您的情況下更喜歡基於 Log4j 2.x 的 SLF4J。 由於類加載器從commons-logging
或spring-jcl
隨機加載org.apache.commons.logging.LogFactory
類,因此您可能會遇到兩種問題:
commons-logging
版本,則ServiceLoader
隨機加載log4j-jcl
的實現或spring-jcl
的實現。 您已經在回答中解決了這個案例。spring-jcl
的版本,將使用 SLF4J 后端。為了解決所有這些潛在的問題,我會:
commons-logging
並保留克隆spring-jcl
。 更好的是,我會排除兩者並使用確定性jcl-over-slf4j
(始終使用 SLF4J 的完整 JCL 替換)log4j-jcl
因為不再需要它(只有原始commons-logging
需要它),log4j-slf4j-impl
SLF4J 綁定。 此解決方案向您的日志記錄配置(JCL -> SLF4J -> Log4j 2.x)添加了一個額外的 API,但保證了穩定性。 這也是spring-boot-starter-log4j2
工作方式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.