log4j2使用及log4j2.xml分析

雪落南城發表於2021-01-03

我們使用slf4j + log4j2作為專案的日誌組合

pom

 <!-- slf4j核心包-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.13</version>
        </dependency>

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.13.3</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.13.3</version>
            <scope>compile</scope>
        </dependency>
        
        <!-- log4j2 非同步日誌依賴-->
        <dependency>
            <groupId>com.lmax</groupId>
            <artifactId>disruptor</artifactId>
            <version>3.3.4</version>
        </dependency>

demo

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Slf4j {

    @Test
    public void test() {
        Logger logger = LoggerFactory.getLogger("slf4j");

        logger.error("error");
        logger.info("info");
        logger.debug("debug");
        logger.warn("warn");
    }
}

控制檯輸出:
在這裡插入圖片描述
因為log4j2預設輸出級別是error,這是我們沒有配置log4j2.xml的輸出,
接下來我們新增一個log4j2的配置檔案

log4.xml

<?xml version="1.0" encoding="UTF-8"?>

<!--
    status="warn" 日誌框架本身的輸出日誌級別
    monitorInterval="5" 自動載入配置檔案的間隔時間,不低於5-->
<configuration status="OFF" monitorInterval="5">

    <!--
        集中配置屬性管理,使用時通過${}
        類似於pom檔案中的定義
    -->
    <properties>
        <property name="LOG_HOME">/logs</property>
    </properties>

    <!-- 日誌處理 -->
    <appenders>
        <!-- 控制檯輸出 -->
        <Console name="CONSOLE" target="SYSTEM_OUT">
            <!-- 日誌輸出格式 -->
            <PatternLayout pattern="%d [%X{applicationName}] [%X{traceId}] [%X{spanName}] [%t] [%-5level] [%c{36}] %M %L - %msg%xEx%n"/>
        </Console>

        <!-- 日誌檔案輸出 -->
        <File name="file" fileName="${LOG_HOME}/myFile.log">
            <!-- 日誌輸出格式 -->
            <PatternLayout pattern="%d [%X{applicationName}] [%X{traceId}] [%X{spanName}] [%t] [%-5level] [%c{36}] %M %L - %msg%xEx%n"/>
        </File>

        <!-- 非同步appender -->
        <Async name="Async">
            <AppenderRef ref="ROLLING"/>
        </Async>

        <!-- 隨機讀寫流日誌檔案輸出 效率提升 -->
        <RandomAccessFile name="accessFile" fileName="${LOG_HOME}/myAccFile.log">
            <!-- 日誌輸出格式 -->
            <PatternLayout pattern="%d [%X{applicationName}] [%X{traceId}] [%X{spanName}] [%t] [%-5level] [%c{36}] %M %L - %msg%xEx%n"/>
        </RandomAccessFile>

        <!-- 按照一定規則拆分日誌檔案的 appender 、
            filePattern:拆分後的檔案命名
        -->
        <RollingFile name="ROLLING" fileName="logs/stdout.log" filePattern="logs/stdout.%d{yyyy-MM-dd}-%i.log.gz">
            <!-- 日誌級別過濾器 -->
            <ThresholdFilter level="debug" onMatch="ACCEPT"></ThresholdFilter>
            <!-- 日誌輸出格式 -->
            <PatternLayout pattern="%d [%X{applicationName}] [%X{traceId}] [%X{spanName}] [%t] [%-5level] [%c{36}] %M %L - %msg%xEx%n"/>
            <!-- 具體拆分策略 -->
            <Policies>
                <!-- 在系統啟動時就生成一個日誌檔案 -->
                <OnStartupTriggeringPolicy />
                <!-- 按照大小拆分 -->
                <SizeBasedTriggeringPolicy size="10 MB"/>
                <!-- 按照時間節點進行拆分 規則根據前邊的filePattern定義-->
                <TimeBasedTriggeringPolicy modulate="true" interval="1"/>
            </Policies>
            <!-- 在同一個目錄下 檔案的個數 防止日誌檔案過多佔滿磁碟 超過會進行覆蓋-->
            <DefaultRolloverStrategy max="20"/>
        </RollingFile>
    </appenders>
    <!-- logger定義 -->
    <loggers>
        <!-- 使用rootLogger進行配置 -->
        <Root level="info">
            <!-- 指定使用哪個appender,appenders標籤中定義的 -->
            <AppenderRef ref="CONSOLE"/>
            <AppenderRef ref="ROLLING"/>

            <!-- 使用非同步的appender 生產中不推薦使用-->
            <AppenderRef ref="Async"/>
        </Root>

        <!-- 使用非同步logger 非同步輸出日誌,注意asyncLogger 和 asyncAppender是兩種不同的非同步實現方式
            name:可以是包路徑比如:org.apache,使用方式:Logger logger=LoggerFactory.getLogger(getClass());那麼所有org.apache包下的日誌都寫在這個asynclogger
                 也可以是自定義名字比如:myLogger,使用方式:Logger logger=LoggerFactory.getLogger("myLogger");那麼該日誌寫在這個asynclogger
            includeLocation:關閉日誌記錄的行號資訊
            additivity="false":不再繼承rootLogger物件
        -->
        <AsyncLogger name="myAsyncLogger" level="trace" includeLocation="false" additivity="false">
            <AppenderRef ref="file"/>
        </AsyncLogger>
    </loggers>
</configuration>

非同步輸出日誌

log4j2提供了兩種非同步實現方式,一個是通過AsyncAppender,對應標籤appenders中的,另一個是AsyncLogger,對應標籤loggers;我們選擇AsyncLogger,因為AsyncAppender效能提升不大

使用時需要新增maven依賴

        <!-- log4j2 非同步日誌依賴-->
        <dependency>
            <groupId>com.lmax</groupId>
            <artifactId>disruptor</artifactId>
            <version>3.3.4</version>
        </dependency>

AsyncLogger配置又分為兩種:

1、全域性配置

無需修改log4j2.xml,所有日誌輸出全部非同步
新增log4j2.component.properties檔案
內容:
Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector

2、區域性配置

需要修改log4j2.xml
loggers標籤中增加

        <!-- 使用非同步logger 非同步輸出日誌,注意asyncLogger 和 asyncAppender是兩種不同的非同步實現方式
            name:可以是包路徑比如:org.apache,使用方式:Logger logger=LoggerFactory.getLogger(getClass());那麼所有org.apache包下的日誌都寫在這個asynclogger
                 也可以是自定義名字比如:myLogger,使用方式:Logger logger=LoggerFactory.getLogger("myLogger");那麼該日誌寫在這個asynclogger
            includeLocation:關閉日誌記錄的行號資訊
            additivity="false":不再繼承rootLogger物件
        -->
        <AsyncLogger name="myAsyncLogger" level="trace" includeLocation="false" additivity="false">
            <AppenderRef ref="file"/>
        </AsyncLogger>

相關文章