2024/6/3

log4j2

java 開發環境,JDK 預設有提供 logging 機制,但 logging 機制的發展,也是一段精彩的歷史。就以往使用的經驗,從一開始的 log4j,後來換成了 logback + slf4j,到現在這個階段,似乎又要換成 log4j2,因為 log4j2 的效能評估,結果已經是又超過了 logback。

logging framwork 的發展可以參考這一篇文章: Java Logging 的歷史與戰爭

但這種情況也說明了,開放且多元的 java 開發環境,一個必要且熱門的 framework,會吸引大家注意並不斷提出更好的框架,但使用者就得跟著時代不斷的進步。

使用 log4j 用 maven 引用 library,在 pom.xml 的 dependencies 裡面加上 log4j2 及 slf4j。

slf4j 是 logging 的 wrapper,可用一致 API 介面進行程式開發,在不修改程式的狀況下,可替換內部的實作為 logback 或 log4j 或 jdk logging。

    <dependencies>
        <!-- log4j2 + slf4j -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.22.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.22.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.22.1</version>
        </dependency>
    </dependencies>

在 classpath 裡面加上設定檔 log4j2.xml

以下是調整後的設定

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout>
                <Pattern>%d{HH:mm:ss.SSS} [%thread] %-5p %c %L - %m%n</Pattern>
            </PatternLayout>
        </Console>

        <!--
        <File name="FILE" fileName="testweb.log">
            <PatternLayout>
                <Pattern>%d [%thread] %-5p %c %L - %m%n</Pattern>
            </PatternLayout>
        </File>
        -->
        <RollingFile name="RollingFile" fileName="logs/testweb.log" filePattern="logs/testweb-%d{yyyy-MM-dd}-%i.log.gz">
            <PatternLayout>
                <Pattern>%d [%thread] %-5p %c %L - %m%n</Pattern>
            </PatternLayout>
            <Policies>
                <OnStartupTriggeringPolicy />
                <TimeBasedTriggeringPolicy />
                <SizeBasedTriggeringPolicy size="250 MB"/>
            </Policies>
            <DefaultRolloverStrategy>
                <Delete basePath="${baseDir}" maxDepth="2">
                    <IfFileName glob="*/test-*.log.gz" />
                    <IfLastModified age="30d" />
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>
    </Appenders>
    <Loggers>
        <!-- hibernate -->
        <logger name="org.hibernate" level="INFO" />
        <Logger name="org.hibernate.SQL" level="DEBUG" />
        <logger name="org.hibernate.cfg" level="ERROR" />

        <Root level="info">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="RollingFile"/>
        </Root>
    </Loggers>
</Configuration>

RollingFile 的部分可以參考官方說明Log4j 2 Appenders

Policies 的部分,決定什麼時候要 trigger rolling 的機制。OnStartupTriggeringPolicy 代表程式啟動要做一次。TimeBasedTriggeringPolicy 則是跟著 Pattern 裡面日期的最小精度的部分 trigger,目前日期是設定為日,所以這個範例,每天會處理一次。SizeBasedTriggeringPolicy 則是會判斷 log file 的檔案大小 trigger,pattern 部分會因為 %i 這個設定,每次會將檔案改為 -1, -2 這樣的檔名。

DefaultRolloverStrategy 可將超過 30 天,符合glob 設定的 pattern 的檔案刪除。

使用 logging 是透過 sl4j 介面

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HelloWorld {
    Logger log = LoggerFactory.getLogger(this.getClass().getName());
    public void sayHello(){
        log.debug("This will be printed on debug");
        log.info("This will be printed on info");
        log.warn("This will be printed on warn");
        log.error("This will be printed on error");

        log.info("Appending string: {}.", "Hello, World");
    }
}

log4j2 對效能最大的改進點在非同步的 file appender Log4j 2 Appenders

調整 log4j2.xml 設定,基於上面的 RollingFile 增加 Appenders。

bufferSize 預設為 1024,代表可暫存 1024 則 log,必須要設定為 2 的指數。

        <Async name="AsyncRollingFile" bufferSize="262144">
            <AppenderRef ref="RollingFile"/>
        </Async>

然後修改下面的 AppenderRef,就可以換成 AsyncRollingFile

        <Root level="info">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="AsyncRollingFile"/>
        </Root>

References

Log4j2中RollingFile的文件滚动更新机制 - Ye_yang - 博客园

Java Logging Frameworks: log4j vs logback vs log4j2

Log4j; Performance

沒有留言:

張貼留言