Log4J 是 Java 事實標準日誌框架,核心三大組件:**Logger (記錄器)、Appender (輸出目的地)、Layout (格式化)**。本文以 .properties 配置為例,示範從依賴引入到多層級輸出控制的完整流程。
<dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency>log4j-1.2.17.jar 放入 Classpath (如 WEB-INF/lib)。log.properties# === Root Logger ===
log4j.rootLogger=WARN, console
# === 特定 Logger 層級覆蓋 ===
log4j.logger.first=ERROR, console
log4j.logger.first.second=INFO, console
# === Appender 定義 ===
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.SimpleLayout
# 進階:PatternLayout 自訂格式
# log4j.appender.console.layout=org.apache.log4j.PatternLayout
# log4j.appender.console.layout.ConversionPattern=%d{ISO8601} [%t] %-5p %c{2} - %m%n
# 檔案輸出範例 (RollingFileAppender)
# log4j.appender.file=org.apache.log4j.RollingFileAppender
# log4j.appender.file.File=logs/app.log
# log4j.appender.file.MaxFileSize=10MB
# log4j.appender.file.MaxBackupIndex=5
# log4j.appender.file.layout=org.apache.log4j.PatternLayout
# log4j.appender.file.layout.ConversionPattern=%d %p [%c] - %m%n
| 設定 | 含義 |
|---|---|
log4j.rootLogger=WARN, console | 根記錄器預設輸出 WARN 以上 (WARN, ERROR, FATAL) 至 console |
log4j.logger.first=ERROR, console | 名為 first 的 Logger 及其子孫預設 ERROR 以上 |
log4j.logger.first.second=INFO, console | 子記錄器 first.second 獨立設為 INFO 以上 (DEBUG 仍被過濾) |
SimpleLayout | 輸出格式:級別 - 訊息 (如 WARN - root warn) |
package log;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
public class JustLog4j {
// 靜態取得 Logger 實例,名稱對應配置檔層級
private static final Logger rootLogger = Logger.getRootLogger();
private static final Logger firstLogger = Logger.getLogger("first");
private static final Logger secondLogger = Logger.getLogger("first.second");
public static void main(String[] args) {
System.out.println("start");
// 載入配置 (僅需一次,通常放在 ServletContextListener 或 Spring 初始化)
PropertyConfigurator.configure("log.properties");
// === Root Logger 測試 ===
rootLogger.debug("root debug"); // 不輸出 (低於 WARN)
rootLogger.info("root info"); // 不輸出
rootLogger.warn("root warn"); // 輸出
rootLogger.error("root error"); // 輸出
rootLogger.fatal("root fatal"); // 輸出
// === first Logger 測試 (ERROR 以上) ===
firstLogger.debug("first debug"); // 不輸出
firstLogger.info("first info"); // 不輸出
firstLogger.warn("first warn"); // 不輸出 (低於 ERROR)
firstLogger.error("first error"); // 輸出 (兩次,因配置有兩個 appender? 實為範例重複)
firstLogger.fatal("first fatal"); // 輸出
// === first.second Logger 測試 (INFO 以上) ===
secondLogger.debug("second debug"); // 不輸出
secondLogger.info("second info"); // 輸出 (三次)
secondLogger.warn("second warn"); // 輸出 (三次)
secondLogger.error("second error"); // 輸出 (三次)
secondLogger.fatal("second fatal"); // 輸出 (三次)
System.out.println("end");
}
}
start
WARN - root warn
ERROR - root error
FATAL - root fatal
ERROR - firstLogger error
ERROR - firstLogger error
FATAL - firstLogger fatal
FATAL - firstLogger fatal
INFO - secondLogger info
INFO - secondLogger info
INFO - secondLogger info
WARN - secondLogger warn
WARN - secondLogger warn
WARN - secondLogger warn
ERROR - secondLogger error
ERROR - secondLogger error
ERROR - secondLogger error
FATAL - secondLogger fatal
FATAL - secondLogger fatal
FATAL - secondLogger fatal
end
log4j.xml 支援更豐富設定 (Filter, ErrorHandler, AsyncAppender),生產環境建議使用。MDC.put("requestId", UUID.randomUUID().toString()) 注入追蹤 ID,PatternLayout 使用 %X{requestId} 輸出,實現全鏈路日誌關聯。AsyncAppender 或 Logback <async>,將 I/O 移出業務執行緒。