开发log4j配置_从 log4j 迁移到 logback
最近把項目的日志框架從 log4j 遷移到 logback,過程里遇到很多坑,記錄下來
目標
本次遷移的目標就是用 slf4j+logback 的日志框架來取代目前的 slf4j+log4j
如何遷移
基于 slf4j+log4j 的無痛遷移
如果項目本身是采用的 slf4j+log4j 日志架構,遷移到 logback 就比較簡單
第一步:修改依賴
原本是 slf4j+log4,依賴如下
org.slf4j slf4j-apiorg.slf4j slf4j-log4j12log4j log4j遷移到 slf4j+logback,依賴如下
org.slf4j slf4j-apich.qos.logback logback-classic第二步:修改日志配置
logback 的配置文件為 logback.xml,替換掉 log4j.xml,以下示例,配置了輸出日志到控制臺及異步輸出到文件,日志文件按日期滾動;同時支持使用 mdc 打印會話唯一標識 sid
<?xml version="1.0" encoding="UTF-8"?>%date{HH:mm:ss.SSS} [%-5level] [%logger:%L] %mdc{sid:--} - %msg%nUTF-8DEBUG${log.path}/${app.name}.log${log.path}/${app.name}.log.%d{yyyy-MM-dd}%date{HH:mm:ss.SSS} [%-5level] [%logger] %mdc{sid:--} - %msg%nUTF-8DEBUG0第三步:web 項目初始化日志
增加如下依賴
org.logback-extensions logback-ext-spring 0.1.5在 web.xml 里增加如下監聽器
logbackConfigLocationclasspath:config/logback.xmlch.qos.logback.ext.spring.web.LogbackConfigListener直接從 log4j 遷移
項目里依賴了其他一些庫,可以用 maven 命令 mvn dependency:tree 來查看下,都有哪些庫還用到了 log4j,如果這些庫也是 slf4j+log4j 的架構那就萬事大吉,但也有的庫直接用的 log4j,這樣就有點小麻煩了
根據 slf4j 的文檔(http://www.slf4j.org/legacy.html),使用 log4j 橋接器 log4j-over-slf4j 來替換 log4j 依賴:即在所有依賴到 log4j 的庫上排除 log4j 的依賴,并添加 log4j-over-slf4j 依賴,如下
com.refusea.framework framework-service compile log4j log4jorg.slf4j log4j-over-slf4j其他日志框架(jul/jcl/log4j2/...) 和 log4j 類似,slf4j 為其他日志框架提供了 xxx-over-slf4j 橋接器,比如 jcl-over-slf4j,如果用到了對應的日志框架,只需要在依賴里排除該日志框架依賴,并添加對應的橋接器即可
這里要特別提一下 jul(java.util.logging),由于這個日志框架內置在 jdk 內,無法通過置換依賴的方式來橋接,所以需要項目自己調用一下橋接器的方法,在項目初始化時執行如下代碼即可
SLF4JBridgeHandler.removeHandlersForRootLogger();SLF4JBridgeHandler.install();也許是因為這個原因,jul 的橋接器名字是 jul-to-slf4j 而不是 jul-over-sl4fj
小心死循環
使用 slf4j 橋接方式時,需要注意避免死循環,以橋接 log4j 為例說明
slf4j+log4j 要用到 slf4j-log4j12,這個庫的作用是將 log4j 適配到 slf4j,其調用邏輯如下圖
sl4fj+log4j
如果在橋接 log4j 時系統里還存在 slf4j-log4j12 庫,就會導致如下的調用邏輯
slf4j+log4j+log4j橋接死循環
可以發現這樣會導致死循環,解決的辦法很簡單:從所有依賴里排除 slf4j-log4j12 庫
maven-enforcer-plugin
現在你排除了所有可能導致死循環的依賴,但是某天你引入了一個新的依賴,一時疏忽,沒有排查這個新的依賴是否傳遞了 slf4j-logj12,那就存在死循環的風險;另一方面,就算你能保證自己每次都不會疏忽,但是你能保證項目里的其他開發人員也會在引入新依賴時進行檢查嗎?
這種情況,可以使用 maven 插件 maven-enforcer-plugin 來幫我們檢查,把你想要排除的依賴配置一次即可
org.apache.maven.pluginsmaven-enforcer-plugin3.0.0-M2enforceenforce3.2.5maven version must be 3.2.5 or above1.7log4j:*org.apache.logging.log4j:*commons-logging:commons-loggingorg.slf4j:slf4j-log4j12org.slf4j:slf4j-jclorg.slf4j:slf4j-jdk14DO NOT use any other logger framework beyond slf4j+logbackjcl 的坑
jcl,即 The Apache Commons Logging,也是廣泛應用的日志框架,在遷移的過程中,我們會排除該日志組件并用 jcl-over-slf4j 來取代它,并通過 maven-enforcer-plugin 來避免將可能導致死循環的依賴打包
問題是這一套看上去無懈可擊的流程有漏洞:沒有 jcl,maven-assembly-plugin 這個插件無法工作;而且這個插件會把 jcl 強行塞到最終輸出的 zip 里,并不會觸發 maven-enforcer-plugin 配置的排除規則
經過一番研究,發現把 jcl 的 scope 設為 provided 可以解決這個問題
commons-logging commons-logging 1.2provided總結
以上是生活随笔為你收集整理的开发log4j配置_从 log4j 迁移到 logback的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 快递打印云服务器_企业微信支持寄快递查快
- 下一篇: 怎么导入sklearn包_在导入skle