Loggers 配置解析
我們通過下面的例子來理解 log4j 的 Loggers 配置是如何決定日志輸出規則的。
<Loggers><!-- 根Logger:全局配置 --><Root level="debug"><AppenderRef ref="consoleAppender" level="info"/><AppenderRef ref="allFileAppender" level="all"/><AppenderRef ref="debugFileAppender" level="debug"/><AppenderRef ref="infoFileAppender" level="info"/><AppenderRef ref="warnFileAppender" level="warn"/><AppenderRef ref="errorFileAppender" level="error"/></Root><!-- 自定義Logger:特定模塊配置 --><Logger level="trace" name="com.ruoyi.admin.log"><AppenderRef ref="allFileAppender" level="all"/></Logger></Loggers>
這個配置結合了根 Logger 和自定義 Logger,并實現了分模塊、分級別的日志記錄策略。理解關鍵在于層級關系、繼承機制和級別過濾的相互作用。
日志輸出規則
- 層級繼承
- 所有 Logger 默認繼承根 Logger 配置
com.ruoyi.admin.log
及其子包的日志優先使用自定義 Logger 配置。即有子類的情況優先采用子類定義的規則。這點可以類比 Java 中的父類與子類關系。
- additivity 屬性
- 未顯式設置時默認為
true
(即日志會同時傳遞給自定義 Logger 和根 Logger) - 這可能導致重復記錄(稍后詳解)
- 未顯式設置時默認為
- 雙層過濾
日志需通過:- Logger 級別過濾(第一層)
- Appender 級別過濾(第二層)
各 Appender 輸出內容分析
1. 根 Logger 的 Appender(處理非 com.ruoyi.admin.log
包日志)
Appender | 輸出內容 | 實際輸出級別范圍 |
---|---|---|
consoleAppender | 所有包的INFO+日志 | INFO, WARN, ERROR, FATAL |
allFileAppender | 所有包的DEBUG+日志(不包含TRACE) | DEBUG, INFO, WARN, ERROR |
debugFileAppender | 所有包的DEBUG+日志 | DEBUG, INFO, WARN, ERROR |
infoFileAppender | 所有包的INFO+日志 | INFO, WARN, ERROR, FATAL |
warnFileAppender | 所有包的WARN+日志 | WARN, ERROR, FATAL |
errorFileAppender | 所有包的ERROR+日志 | ERROR, FATAL |
📌 注意:根Logger的
level="debug"
過濾掉了TRACE日志,因此allFileAppender
也捕獲不到TRACE
2. 自定義Logger的Appender(專用于com.ruoyi.admin.log
包)
Appender | 輸出內容 | 實際輸出級別范圍 |
---|---|---|
allFileAppender | com.ruoyi.admin.log 包的TRACE+日志 | TRACE, DEBUG, INFO, WARN, ERROR |
3. 關鍵交叉點:com.ruoyi.admin.log
包的日志
由于additivity=true
(默認),該包的日志會同時被:
- 自定義Logger處理
- 根Logger處理
具體輸出示例(以DEBUG日志為例)
- 自定義Logger路徑
DEBUG日志 → 通過trace級別 → allFileAppender(level=all) → 輸出
- 根Logger路徑
DEBUG日志 → 通過debug級別 → 根Logger的Appender二次過濾:
allFileAppender(level=all) → 輸出
debugFileAppender(level=debug) → 輸出
infoFileAppender(level=info) → 丟棄
- …其他同理
結果:重復記錄問題
allFileAppender 會記錄兩次 com.ruoyi.admin.log
的DEBUG日志,表現為 allFileAppender 指定的日志輸出文件中會打印兩次相同的日志。
- 來自自定義Logger
- 來自根Logger
優化建議:避免重復記錄
增加additivity="false"
屬性:
<Logger level="trace" name="com.ruoyi.admin.log" additivity="false"><AppenderRef ref="allFileAppender" level="all"/>
</Logger>
優化后效果:
日志來源 | allFileAppender | 其他Appender |
---|---|---|
非com.ruoyi.admin.log | 根Logger的DEBUG+日志 | 按各自級別過濾 |
com.ruoyi.admin.log | 該包的TRACE+日志 | 不再出現 |
即只有 allFileAppender 能輸出 com.runyi.admin.log 及其子包中的日志。
最終輸出總結(優化后配置)
Appender | 輸出內容 | 覆蓋范圍 |
---|---|---|
consoleAppender | 全局INFO+日志(不含特殊包) | 非特殊包 |
allFileAppender | 全局DEBUG+日志 + 特殊包TRACE+日志 | 所有包,不同級別 |
debugFileAppender | 全局DEBUG+日志(不含特殊包) | 非特殊包 |
infoFileAppender | 全局INFO+日志(不含特殊包) | 非特殊包 |
warnFileAppender | 全局WARN+日志(不含特殊包) | 非特殊包 |
errorFileAppender | 全局ERROR+日志(不含特殊包) | 非特殊包 |
特殊包:
com.ruoyi.admin.log
及其子包
這種配置實現了:
- 生產環境安全:默認只記錄DEBUG+日志
- 關鍵模塊追蹤:特定包記錄最詳細的TRACE日志。可以調試用。
- 分類存儲:不同級別日志分離到不同文件
- 控制臺精簡:只顯示INFO+關鍵信息