Jakarta Commons Logging (JCL) 提供輕量級、與具體日誌實現解耦的門面介面,讓中間件/框架開發者無綁定地記錄日誌,應用層再決定具體實現 (Log4j、JDK 1.4、LogKit 等)。本文從核心概念、快速上手、開發流程、日誌級別規範,到 Log4j 整合實戰與輸出對比,完整呈現 JCL 使用全貌。
JCL 兩大核心抽象:
LogFactory 自動發現順序 (找到即停止):
org.apache.commons.logging.Log 系統屬性log4j → 使用 Log4JLogger 包裝器Jdk14Logger 包裝器SimpleLog (輸出至 System.err)內建實現類:
org.apache.commons.logging.impl.Log4JLogger - Log4j 包裝org.apache.commons.logging.impl.Jdk14Logger - JDK Logging 包裝org.apache.commons.logging.impl.LogKitLogger - Avalon LogKit 包裝org.apache.commons.logging.impl.SimpleLog - 簡易實現,輸出至 stderrorg.apache.commons.logging.impl.NoOpLog - 空實現,不輸出任何內容commons-logging.jar + log4j.jar 放入專案 lib 並加入 Classpathcommons-logging.properties (Classpath 根目錄):
# 使用 Log4j 作為底層實現
org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JCategoryLog
# 可選:JDK 1.4 Logging
# org.apache.commons.logging.Log=org.apache.commons.logging.impl.Jdk14Logger
# 可選:簡易日誌
# org.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class MyClass {
private static final Log log = LogFactory.getLog(MyClass.class);
// ...
}
log.debug("...")、log.info("...") 等按嚴重度高到低:
fatal(Object message)
fatal(Object message, Throwable t)
error(Object message)
error(Object message, Throwable t)
warn(Object message)
warn(Object message, Throwable t)
info(Object message)
info(Object message, Throwable t)
debug(Object message)
debug(Object message, Throwable t)
trace(Object message)
trace(Object message, Throwable t)
防護方法 (避免不必要的字串構建開銷):
isFatalEnabled()
isErrorEnabled()
isWarnEnabled()
isInfoEnabled()
isDebugEnabled()
isTraceEnabled()
// 使用範例
if (log.isDebugEnabled()) {
log.debug("耗時操作結果: " + expensiveComputation());
}
| 級別 | 使用場景 | 輸出期望 |
|---|---|---|
| FATAL | 極其嚴重錯誤,系統即將終止 | 立即顯示於狀態控制台 |
| ERROR | 運行期錯誤、非預期條件 | 立即顯示於狀態控制台 |
| WARN | 棄用 API、接近錯誤狀態、非預期但可繼續 | 立即顯示於狀態控制台 |
| INFO | 有意義的運行期事件 (啟動、關閉、關鍵業務節點) | 立即顯示於狀態控制台 |
| DEBUG | 系統流程細節、診斷資訊 | 僅寫入日誌檔案 |
| TRACE | 極細粒度追蹤 (方法進出、變數值) | 僅寫入日誌檔案 |
原則: 生產環境 Logger 級別通常不低於 INFO,DEBUG/TRACE 僅開發/除錯時啟用。
// Test.java
package sample;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class Test {
private static Log log = LogFactory.getLog(Test.class);
public void log() {
log.debug("Debug info.");
log.info("Info info");
log.warn("Warn info");
log.error("Error info");
log.fatal("Fatal info");
}
public static void main(String[] args) {
new Test().log();
}
}
輸出 (輸出至 stderr,含類別/方法/行號):
DEBUG sample.Test.log(Test.java:13) Debug info.
INFO sample.Test.log(Test.java:14) Info info
WARN sample.Test.log(Test.java:15) Warn info
ERROR sample.Test.log(Test.java:16) Error info
FATAL sample.Test.log(Test.java:17) Fatal info
log4j.jarcommons-logging.properties 指定 Log4JCategoryLoglog4j.properties 配置輸出格式:
log4j.rootLogger=info, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
輸出 (依 PatternLayout 格式,DEBUG 被 rootLogger 級別 INFO 過濾):
INFO [main] - Info info
WARN [main] - Warn info
ERROR [main] - Error info
FATAL [main] - Fatal info
本系列文檔:
本文出自「子孑」部落格,轉載請保留出處:https://zhangjunhd.blog.51cto.com/113473/25135