SpringBoot整合log4j2


1.去除默認的依賴並導入log4j2、lombok依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <exclusions>
        <!-- 引入log4j日志時需去掉默認的logback -->
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<!-- 日志管理log4j2 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
    <version>2.1.0.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

上面log4j2是直接導入了SpringBoot對應的版本,也可以導入spring的版本,兩種二選一:

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.11.2</version>
</dependency>

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.11.2</version>
</dependency>

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.11.2</version>
</dependency>

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.30</version>
</dependency>

2.在資源目錄下新建log4j2.xml文件

1)通用日志記錄:所有等級的日志都記錄在同一個文件中

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

<configuration status="info">
    <Properties>
        <!-- 聲明日志文件存儲的目錄 -->
        <Property name="LOG_HOME">E:/logs/app/</Property>
        <Property name="APP_NAME">log</Property>
        <Property name="LOG_PATTERN"
                  value="%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread][%class{36}:%line] - %msg%n"></Property>
    </Properties>
    <Appenders>
        <!--輸出控制台的配置-->
        <Console name="Console" target="SYSTEM_OUT">
            <!--控制台只輸出level及以上級別的信息(onMatch),其他的直接拒絕(onMismatch)-->
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
            <!-- 輸出日志的格式-->
            <PatternLayout pattern="${LOG_PATTERN}"/>
        </Console>

        <!--輸出日志到文件的配置,每次大小超過size,則這size大小的日志會自動存入按年份-月份建立的文件夾下面-->
        <RollingFile name="RollingFile" fileName="${LOG_HOME}/${APP_NAME}.log"
                     filePattern="${LOG_HOME}/%d{yyyy-MM}/%d{yyyy-MM-dd}_%i.log">
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
            <!-- 輸出日志的格式-->
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="100MB"/>
            </Policies>
            <!-- 最多保留文件數 -->
            <DefaultRolloverStrategy max="365"/>
        </RollingFile>
    </Appenders>
    <!--然后定義Logger,只有定義了Logger並引入的Appender,Appender才會生效。Root中level配置了日志級別,可配置其他級別-->
    <Loggers>
        <Root level="info">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="RollingFile"/>
        </Root>
    </Loggers>

</configuration>

在配置中指定了日志存儲的目錄是E:\logs\app,日志文件使用日期作為重要區分的條件。

2)分級日志記錄:不同等級的日志記錄到對應的文件中

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

<configuration status="info">
    <Properties>
        <!-- 聲明日志文件存儲的目錄 -->
        <Property name="LOG_HOME">E:/logs/app/</Property>
        <Property name="LOG_PATTERN"
                  value="%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread][%class{36}:%line] - %msg%n"></Property>
    </Properties>
    <Appenders>
        <!--輸出控制台的配置-->
        <Console name="Console" target="SYSTEM_OUT">
            <!--控制台只輸出level及以上級別的信息(onMatch),其他的直接拒絕(onMismatch)-->
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
            <!-- 輸出日志的格式-->
            <PatternLayout pattern="${LOG_PATTERN}"/>
        </Console>
        <!-- ERROR級別日志 -->
        <RollingFile name="infoAppender" fileName="${LOG_HOME}/info.log"
                     filePattern="${LOG_HOME}/%d{yyyy-MM}/%d{yyyy-MM-dd}_info.log">
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="100MB"/>
            </Policies>
        </RollingFile>
        <!-- ERROR級別日志 -->
        <RollingFile name="errorAppender" fileName="${LOG_HOME}/error.log"
                     filePattern="${LOG_HOME}/%d{yyyy-MM}/%d{yyyy-MM-dd}_error.log">
            <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="100MB" />
            </Policies>
        </RollingFile>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="infoAppender"/>
            <AppenderRef ref="errorAppender"/>
        </Root>
    </Loggers>

</configuration>

對於是否分級記錄,根據需求決定。兩者選一即可。

3.在配置文件配置log4j2文件的位置

logging.config = classpath:log4j2.xml

4.添加測試方法進行測試

package com.zys.springboottestexample;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class SpringbootTestExampleApplicationTests {

    //創建日志對象
    Logger logger = LogManager.getLogger(this.getClass());

    @Test
    void test() {
        logger.info("我是info日志");
        logger.warn("我是warn日志");
        logger.error("我是error日志");
    }

}

執行測試方法后,在控制台打印了日志,同時在對應的目錄生成了日志文件,其內容和控制台是一致的。

5.在測試類上使用@Sl4j注解輸出日志

import lombok.extern.slf4j.Slf4j;

...
@Slf4j
public class SpringbootTestExampleApplicationTests {
    
   ...

   @Test
    public void test2() {
        log.info("天氣真熱啊");
        log.error("天氣真熱啊");
    }

}

只寫了關鍵的代碼。使用sl4j時,直接使用log對象即可進行日志的輸出。這里分別演示了使用log4j2和sl4j進行日志的輸出和存儲到日志,可根據習慣選擇使用哪一種方式。使用sl4j輸出時實際上會轉成log4j2日志進行輸出。

6.日志占位符

當需要動態的輸出日志及參數時,可以使用占位符 "{}"進行占位。可以寫多個占位符,它會根據后面的參數進行位置匹配填充。log4j2和sl4j用法一樣,參考如下:

logger.info("你的姓名是:{},年齡是:{}", "張三", 20);
log.info("你的姓名是:{},年齡是:{}", "張三", 20);

控制台打印的日志如下圖:

上述的實例中,有兩個大括號,第一個大括號匹配后面的第一個參數“張三”,第二個大括號匹配第二個參數20。依次類推。這樣可以減少字符串的拼接。

7.使用原生的logback

相比於log4j2,logback是有其自己的優勢的,其中有一點是它對sql日志的打印配置非常簡單,而log4j2配置會繁雜一些。下面看logback.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="false" scanPeriod="60 seconds" debug="false">
    <!-- 定義日志的根目錄 -->
    <property name="LOG_HOME" value="E:/logs/app" />
    <!-- 定義日志文件名稱 -->
    <property name="appName" value="log"></property>
    <!-- 定義生成的文件夾 -->
    <timestamp key="package" datePattern="yyyy-MM"/>
    <!-- ch.qos.logback.core.ConsoleAppender 表示控制台輸出 -->
    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
        <!--
        日志輸出格式:
            %d表示日期時間,
            %thread表示線程名,
            %-5level:級別從左顯示5個字符寬度
            %logger{50} 表示logger名字最長50個字符,否則按照句點分割。
            %msg:日志消息,
            %n是換行符
        -->
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern>
        </layout>
    </appender>

    <!-- 滾動記錄文件,先將日志記錄到指定文件,當符合某個條件時,將日志記錄到其他文件 -->
    <appender name="appLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 指定日志文件的名稱 -->
        <file>${LOG_HOME}/${appName}.log</file>
        <!--
        當發生滾動時,決定 RollingFileAppender 的行為,涉及文件移動和重命名
        TimeBasedRollingPolicy: 最常用的滾動策略,它根據時間來制定滾動策略,既負責滾動也負責出發滾動。
        -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--
            滾動時產生的文件的存放位置及文件名稱 %d{yyyy-MM-dd}:按天進行日志滾動
            %i:當文件大小超過maxFileSize時,按照i進行文件滾動
            -->
            <fileNamePattern>${LOG_HOME}/${package}/%d{yyyy-MM-dd}_%i.log</fileNamePattern>
            <!--
            可選節點,控制保留的歸檔文件的最大數量,超出數量就刪除舊文件。假設設置每天滾動,
            且maxHistory是365,則只保存最近365天的文件,刪除之前的舊文件。注意,刪除舊文件是,
            那些為了歸檔而創建的目錄也會被刪除。
            -->
            <MaxHistory>365</MaxHistory>
            <!--
            當日志文件超過maxFileSize指定的大小是,根據上面提到的%i進行日志文件滾動 注意此處配置SizeBasedTriggeringPolicy是無法實現按文件大小進行滾動的,
       必須配置timeBasedFileNamingAndTriggeringPolicy
--> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <!-- 日志輸出格式: --> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [ %thread ] - [ %-5level ] [ %logger{50} : %line ] - %msg%n</pattern> </layout> </appender> <!-- logger主要用於存放日志對象,也可以定義日志類型、級別 name:表示匹配的logger類型前綴,也就是包的前半部分 level:要記錄的日志級別,包括 TRACE < DEBUG < INFO < WARN < ERROR additivity:作用在於children-logger是否使用 rootLogger配置的appender進行輸出, false:表示只用當前logger的appender-reftrue: 表示當前logger的appender-ref和rootLogger的appender-ref都有效 --> <!-- Spring framework logger --> <logger name="org.springframework" level="debug" additivity="false"></logger> <!-- root與logger是父子關系,沒有特別定義則默認為root,任何一個類只會和一個logger對應, 要么是定義的logger,要么是root,判斷的關鍵在於找到這個logger,然后判斷這個logger的appender和level。 --> <root level="info"> <appender-ref ref="stdout" /> <appender-ref ref="appLogAppender" /> </root> </configuration>

配置后,只需要在配置文件配置日志的級別即可:

#配置打印日志
logging:
  level:
    com.zys.demo: debug

配置不同的日志級別,就打印不同級別的日志。

對於logback和log4j2,各自有不同的優勢,但也有一定的問題。比如現在有個需求是按天生成日志文件,對於開發環境來說,使用默認的logback即可達到要求,但生產環境必須使用log4j2,若使用logback則不會自動切分日志文件,達不到要求。暫時不清楚問題出在哪里,故暫時按這種方式去處理。具體做法就是在開始時使用logback,而打包時使用log4j2,具體以pom.xml進行切換:

        <!-- *********************************** -->
        <!--
            開發時使用logback,此次需要注釋,
            正式環境使用log4j2,此處需要打開
        -->
        <!-- 引入log4j日志去掉默認的logback -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- 日志管理log4j2 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <!-- *********************************** -->

當然各自的配置文件xml不能少。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM