延續基礎配置,本文深入探討 Log4j 在 Web 應用中的整合部署,重點覆蓋 Tomcat 環境下的啟動初始化、Servlet 配置、詳細配置語法與進階用法。
在 Web 應用中,Log4j 無法像獨立應用那樣自動發現配置文件,需通過 Servlet 在容器啟動時主動初始化。
<servlet>
<servlet-name>log4j</servlet-name>
<servlet-class>com.apache.jakarta.log4j.Log4jInit</servlet-class>
<init-param>
<param-name>log4j</param-name>
<param-value>/WEB-INF/log4j.properties</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
package com.apache.jakarta.log4j;
import org.apache.log4j.PropertyConfigurator;
import javax.servlet.http.*;
public class Log4jInit extends HttpServlet {
public void init() {
String prefix = getServletContext().getRealPath("/");
String file = getInitParameter("log4j");
System.out.println("................log4j start");
if (file != null) {
PropertyConfigurator.configure(prefix + file);
}
}
public void doGet(HttpServletRequest req, HttpServletResponse res) {}
}
關鍵點:load-on-startup>1 確保容器啟動時優先加載;getRealPath("/") 獲取 Web 應用物理路徑,拼接配置文件相對路徑。
# 根 Logger 配置:級別 INFO,兩個 Appender (A1 控制台, R 文件)
log4j.rootLogger=INFO, A1, R
# A1: ConsoleAppender - 控制台輸出
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n
# R: RollingFileAppender - 滾動文件輸出
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=log4j.log
log4j.appender.R.MaxFileSize=100KB
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout=org.apache.log4j.TTCCLayout
| 配置項 | 說明 | 示例值 |
|---|---|---|
| log4j.rootLogger | 根記錄器:級別 + Appender 列表 | INFO, A1, R |
| log4j.appender.{name} | Appender 實現類 | org.apache.log4j.ConsoleAppender |
| log4j.appender.{name}.layout | Layout 實現類 | org.apache.log4j.PatternLayout |
| log4j.appender.{name}.layout.ConversionPattern | 輸出格式模式 | %-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n |
| log4j.appender.R.MaxFileSize | 單個日誌文件最大值 | 100KB, 10MB |
| log4j.appender.R.MaxBackupIndex | 備份文件保留數量 | 1, 5, 10 |
import org.apache.log4j.Logger;
public class MyService {
private static final Logger logger = Logger.getLogger(MyService.class);
public void processOrder(Order order) {
logger.info("開始處理訂單: " + order.getId());
try {
// 業務邏輯
logger.debug("驗證訂單詳情: " + order.getDetails());
// ...
logger.info("訂單處理完成: " + order.getId());
} catch (Exception e) {
logger.error("訂單處理失敗: " + order.getId(), e); // 附帶堆棧追蹤
}
}
}
通過調整配置文件級別,無需重新編譯部署即可控制日誌輸出粒度:
rootLogger=WARN,僅記錄警告及以上,減少 I/O 開銷DEBUG,獲取詳細執行軌跡log4j.logger.com.myapp.payment=DEBUG 僅對支付模組開啟調試log4j.appender.DB=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.DB.URL=jdbc:mysql://localhost/logdb
log4j.appender.DB.username=root
log4j.appender.DB.password=secret
log4j.appender.DB.sql=INSERT INTO LOGS (LEVEL, LOGGER, MESSAGE, TIMESTAMP) VALUES ('%p', '%c', '%m', '%d')
log4j.appender.DB.layout=org.apache.log4j.PatternLayout
高併發場景下,可使用 AsyncAppender(需 Log4j 1.2.15+)將日誌寫入解耦至背景線程:
log4j.appender.ASYNC=org.apache.log4j.AsyncAppender
log4j.appender.ASYNC.BufferSize=500
log4j.appender.ASYNC.appenderRef=R
log4j-1.2.x.jar 放入 $TOMCAT_HOME/common/lib(共享)或 Web 應用 WEB-INF/lib(隔離)/WEB-INF/log4j.properties 或 /WEB-INF/classes/log4j.propertiesLog4jInit Servlet 僅在 web.xml 配置一次| 現象 | 可能原因 | 解決方案 |
|---|---|---|
| 無日誌輸出 | 配置文件未被加載 | 檢查 Servlet 配置、路徑拼接、load-on-startup |
| 重複日誌 | 根 Logger 與子 Logger 同時輸出 | 設置 log4j.additivity.{loggerName}=false |
| 文件不滾動 | MaxFileSize/MaxBackupIndex 配置錯誤 | 檢查單位(KB/MB/GB)、權限、磁盤空間 |
| 中文亂碼 | 文件編碼與 JVM 編碼不一致 | 設置 -Dfile.encoding=UTF-8 或 Layout 指定編碼 |
掌握 Log4j 在 Web 容器中的初始化機制與進階配置,能構建可維護、高性能、適應不同環境的日誌系統。