首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Log4j 2.x 實戰指南:從 Maven 依賴到異步日誌、RollingFile、Web 容器適配全流程

     編輯:Java 相關知識

為什麼選 Log4j 2?

  • **性能**:基於 LMAX Disruptor 的異步日誌,吞吐量比 Log4j 1.x / Logback 高 10 倍+。
  • **無垃圾**:異步模式下幾乎零 GC 壓力。
  • **插件化**:Appender/Layout/Filter 熱插拔,配置靈活。
  • **Java 9+ 模塊化支持**:自動模塊名 org.apache.logging.log4j。

Maven 依賴(最小集合)

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.23.1</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.23.1</version>
</dependency>
<!-- Web 專用:Servlet 容器自動初始化/關閉 -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-web</artifactId>
    <version>2.23.1</version>
</dependency>
<!-- 可選:SLF4J 橋接,統一日誌門面 -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j2-impl</artifactId>
    <version>2.23.1</version>
</dependency>

核心配置文件 log4j2.xml(放在 src/main/resources)

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="30">
    <!-- 1. 定義所有 Appender -->
    <Appenders>
        <!-- 控制台:開發調試用 -->
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %logger{36} %L %M - %msg%n"/>
        </Console>

        <!-- 錯誤專用文件:每次啟動清空,只記 ERROR 及以上 -->
        <File name="ErrorFile" fileName="${sys:log.dir}/error.log" append="false">
            <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout charset="UTF-8" pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger{36} %L %M - %msg%n"/>
        </File>

        <!-- 滾動文件:按大小 + 時間雙重觸發,自動壓縮歸檔 -->
        <RollingFile name="RollingFile" 
            fileName="${sys:log.dir}/app.log"
            filePattern="${sys:log.dir}/archive/%d{yyyy-MM}/app-%d{yyyy-MM-dd}-%i.log.gz">
            <PatternLayout charset="UTF-8" pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger{36} %L %M - %msg%n"/>
            <Policies>
                <SizeBasedTriggeringPolicy size="100 MB"/>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
            </Policies>
            <DefaultRolloverStrategy max="20"/>
        </RollingFile>

        <!-- 異步 Appender:包裝上述任意 Appender,實現高吞吐 -->
        <Async name="AsyncRoot" bufferSize="8192">
            <AppenderRef ref="RollingFile"/>
            <AppenderRef ref="ErrorFile"/>
            <AppenderRef ref="Console"/>
        </Async>
    </Appenders>

    <!-- 2. 定義 Logger -->
    <Loggers>
        <!-- 根 Logger:綁定異步根 Appender -->
        <Root level="INFO">
            <AppenderRef ref="AsyncRoot"/>
        </Root>

        <!-- 特定包級別覆蓋 -->
        <Logger name="com.example.dao" level="DEBUG" additivity="false">
            <AppenderRef ref="AsyncRoot"/>
        </Logger>
        <Logger name="org.springframework" level="WARN"/>
    </Loggers>
</Configuration>

Java 代碼中使用

public class OrderService {
    // 靜態常量,類名自動作為 Logger 名
    private static final Logger LOG = LogManager.getLogger();

    public void createOrder(OrderDTO dto) {
        LOG.info("開始創建訂單: {}", dto.getOrderNo());
        try {
            // 業務邏輯...
            LOG.debug("訂單入庫成功, ID: {}", orderId);
        } catch (Exception e) {
            LOG.error("創建訂單失敗", e); // 異常堆棧自動記錄
            throw new BizException("下單失敗", e);
        }
    }
}

Web 容器適配(Tomcat / Jetty / Undertow)

引入 log4j-web 後,**無需任何 web.xml 配置**,ServletContainerInitializer 會自動:

  1. 啟動時初始化 Log4j 上下文,掃描 log4j2.xml。
  2. 2. 註冊 Log4jServletFilter 將請求上下文(MDC)綁定到線程,支持 %X{requestId} 等參數。 3. 銷毀時優雅關閉 Log4j,刷新異步隊列,釋放文件句柄。

若容器不支持 Servlet 3.0+(極少見),需在 web.xml 手動聲明:

<listener>
    <listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
</listener>
<filter>
    <filter-name>log4jServletFilter</filter-name>
    <filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>log4jServletFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

異步日誌最佳實踐

模式配置方式適用場景備註
全局異步JVM 參數 -Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector極高吞吐、日誌量大所有 Logger 自動異步,需 JDK 8+
混合異步配置文件用 <Async name="AsyncRoot"> 包裝具體 Appender大多數生產環境靈活控制哪些 Appender 異步
同步無特殊配置開發、測試、低併發異常堆棧即時可見,調試方便

建議:生產環境採用 **混合異步**(如上配置),核心業務 Appender 異步,控制台同步輸出以便即時觀察。

常見坑點速查

  1. status="WARN":Configuration 節點屬性,控制 Log4j 自身啟動日誌級別,生產建議 ERROR 或 OFF。
  2. monitorInterval="30":熱加載間隔(秒),修改 log4j2.xml 30 秒內自動生效,無需重啟。
  3. ${sys:log.dir}:啟動參數 -Dlog.dir=/var/log/myapp 指定日誌目錄,避免硬編碼路徑。
  4. **MDC 使用**:MDC.put("traceId", traceId) → 模式 %X{traceId},鏈路追蹤必備。
  5. **關閉 Hook**:Spring Boot 應用關閉時會自動調用 LogManager.shutdown(),獨立應用需手動註冊 Runtime.getRuntime().addShutdownHook(...)。

掌握上述配置與最佳實踐,即可在項目中穩健落地 Log4j 2,享受高性能、可維護、可觀測的日誌系統。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved