SpringBoot—整合log4j2入門和log4j2.xml配置詳解

技術公眾號:後端技術解憂鋪
關注微信公眾號:CodingTechWork,一起學習進步。

引言

  對於一個線上程式或者服務而言,重要的是要有日誌輸出,這樣才能方便運維。而日誌的輸出需要有一定的規劃,如日誌命名、日誌大小,日誌分割的文件個數等。在Spring的框架下,我們可以使用log4j來進行日誌的設置,高版本的SpringBoot會使用log4j2

介紹

log4j2概述

  截取官網的原話:Apache Log4j 2 is an upgrade to Log4j that provides significant improvements over its predecessor, Log4j 1.x, and provides many of the improvements available in Logback while fixing some inherent problems in Logback』s architecture.
  Log4j其實可以理解為log for java,所以是java的日誌框架,提供日誌服務,而Log4j 2是Log4j的升級版本,性能比logback好。
  日誌級別優先順序從低到高:ALL、DEBUG、 INFO、 WARN、 ERROR、FATAL、 OFF。一般官網建議就使用DEBUG、INFO、WARN和ERROR這四個,但是我們可以加一個ALL最低級別的來進行總日誌的輸出。日誌的登記越高,打出的日誌越少。

log4j2的pom依賴

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>

這邊要注意的是:

  1. 在引入log4j2時,需要排除掉Logback日誌框架的依賴即。
                    <artifactId>spring-boot-starter-logging</artifactId>
  1. 如果是1.3.x及以下版本的Spring Boot才支援log4j的日誌配置。
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j</artifactId>
        </dependency>

log4j2.xml配置路徑

  log4j2一般可以通過xml,json,yaml或者properties形式文件來實現,我們這邊主要介紹xml文件格式。

默認路徑

  引入log4j2依賴後,默認在src/main/resources目錄下加入log4j2.xml配置文件對日誌進行配置即可,然後在application.yml中進行訪問路徑的配置。

  示例如下:

  1. log4j2.xml部署位置
    在程式碼工程中的src/main/resources目錄下放入配置文件。
  2. yml配置
#日誌配置 無特殊需求無需更改
logging:
  config:  classpath:log4j2.xml
  level:
    root: INFO
    javax.activation: info
    org.apache.catalina: INFO
    org.apache.commons.beanutils.converters: INFO
    org.apache.coyote.http11.Http11Processor: INFO
    org.apache.http: INFO
    org.apache.tomcat: INFO
    org.springframework: INFO
    com.chinamobile.cmss.bdpaas.resource.monitor: DEBUG

自定義部署位置

當然我們也可以在微服務部署的config/目錄下放置,然後在application.yml中進行訪問路徑的配置。
  示例如下:我們的micro-service01部署中配置的log4j2.xml路徑。

  1. log4j2.xml部署位置
[userA@linux01 config]$ pwd
/home/userA/SpringBoot/micro-service01/config
[userA@linux01 config]$ ll
total 24
-rwxr-xr-x 1 userA userA 5938 Sep  9 16:30 application.yml
-r-------- 1 userA userA 8342 Sep  8 16:33 log4j2.xml
  1. yml配置
#日誌配置 無特殊需求無需更改
logging:
  config: /home/userA/SpringBoot/micro-service01/config/log4j2.xml
  level:
    root: INFO
    javax.activation: info
    org.apache.catalina: INFO
    org.apache.commons.beanutils.converters: INFO
    org.apache.coyote.http11.Http11Processor: INFO
    org.apache.http: INFO
    org.apache.tomcat: INFO
    org.springframework: INFO
    com.chinamobile.cmss.bdpaas.resource.monitor: DEBUG

log4j2.xml配置詳解

xml配置模板

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<!--<Configuration status="WARN" monitorInterval="30"> -->
    <properties>
        <property name="LOG_HOME">./service-logs</property>
    </properties>
    <Appenders>
        <!--*********************控制台日誌***********************-->
        <Console name="consoleAppender" target="SYSTEM_OUT">
            <!--設置日誌格式及顏色-->
            <PatternLayout
                    pattern="%style{%d{ISO8601}}{bright,green} %highlight{%-5level} [%style{%t}{bright,blue}] %style{%C{}}{bright,yellow}: %msg%n%style{%throwable}{red}"
                    disableAnsi="false" noConsoleNoAnsi="false"/>
        </Console>

        <!--*********************文件日誌***********************-->
        <!--all級別日誌-->
        <RollingFile name="allFileAppender"
                     fileName="${LOG_HOME}/all.log"
                     filePattern="${LOG_HOME}/$${date:yyyy-MM}/all-%d{yyyy-MM-dd}-%i.log.gz">
            <!--設置日誌格式-->
            <PatternLayout>
                <pattern>%d %p %C{} [%t] %m%n</pattern>
            </PatternLayout>
            <Policies>
                <!-- 設置日誌文件切分參數 -->
                <!--<OnStartupTriggeringPolicy/>-->
                <!--設置日誌基礎文件大小,超過該大小就觸發日誌文件滾動更新-->
                <SizeBasedTriggeringPolicy size="100 MB"/>
                <!--設置日誌文件滾動更新的時間,依賴於文件命名filePattern的設置-->
                <TimeBasedTriggeringPolicy/>
            </Policies>
            <!--設置日誌的文件個數上限,不設置默認為7個,超過大小後會被覆蓋;依賴於filePattern中的%i-->
            <DefaultRolloverStrategy max="100"/>
        </RollingFile>

        <!--debug級別日誌-->
        <RollingFile name="debugFileAppender"
                     fileName="${LOG_HOME}/debug.log"
                     filePattern="${LOG_HOME}/$${date:yyyy-MM}/debug-%d{yyyy-MM-dd}-%i.log.gz">
            <Filters>
                <!--過濾掉info及更高級別日誌-->
                <ThresholdFilter level="info" onMatch="DENY" onMismatch="NEUTRAL"/>
            </Filters>
            <!--設置日誌格式-->
            <PatternLayout>
                <pattern>%d %p %C{} [%t] %m%n</pattern>
            </PatternLayout>
            <Policies>
                <!-- 設置日誌文件切分參數 -->
                <!--<OnStartupTriggeringPolicy/>-->
                <!--設置日誌基礎文件大小,超過該大小就觸發日誌文件滾動更新-->
                <SizeBasedTriggeringPolicy size="100 MB"/>
                <!--設置日誌文件滾動更新的時間,依賴於文件命名filePattern的設置-->
                <TimeBasedTriggeringPolicy/>
            </Policies>
            <!--設置日誌的文件個數上限,不設置默認為7個,超過大小後會被覆蓋;依賴於filePattern中的%i-->
            <DefaultRolloverStrategy max="100"/>
        </RollingFile>

        <!--info級別日誌-->
        <RollingFile name="infoFileAppender"
                     fileName="${LOG_HOME}/info.log"
                     filePattern="${LOG_HOME}/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log.gz">
            <Filters>
                <!--過濾掉warn及更高級別日誌-->
                <ThresholdFilter level="warn" onMatch="DENY" onMismatch="NEUTRAL"/>
            </Filters>
            <!--設置日誌格式-->
            <PatternLayout>
                <pattern>%d %p %C{} [%t] %m%n</pattern>
            </PatternLayout>
            <Policies>
                <!-- 設置日誌文件切分參數 -->
                <!--<OnStartupTriggeringPolicy/>-->
                <!--設置日誌基礎文件大小,超過該大小就觸發日誌文件滾動更新-->
                <SizeBasedTriggeringPolicy size="100 MB"/>
                <!--設置日誌文件滾動更新的時間,依賴於文件命名filePattern的設置-->
                <TimeBasedTriggeringPolicy interval="1" modulate="true />
            </Policies>
            <!--設置日誌的文件個數上限,不設置默認為7個,超過大小後會被覆蓋;依賴於filePattern中的%i-->
            <!--<DefaultRolloverStrategy max="100"/>-->
        </RollingFile>

        <!--warn級別日誌-->
        <RollingFile name="warnFileAppender"
                     fileName="${LOG_HOME}/warn.log"
                     filePattern="${LOG_HOME}/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log.gz">
            <Filters>
                <!--過濾掉error及更高級別日誌-->
                <ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
            </Filters>
            <!--設置日誌格式-->
            <PatternLayout>
                <pattern>%d %p %C{} [%t] %m%n</pattern>
            </PatternLayout>
            <Policies>
                <!-- 設置日誌文件切分參數 -->
                <!--<OnStartupTriggeringPolicy/>-->
                <!--設置日誌基礎文件大小,超過該大小就觸發日誌文件滾動更新-->
                <SizeBasedTriggeringPolicy size="100 MB"/>
                <!--設置日誌文件滾動更新的時間,依賴於文件命名filePattern的設置-->
                <TimeBasedTriggeringPolicy/>
            </Policies>
            <!--設置日誌的文件個數上限,不設置默認為7個,超過大小後會被覆蓋;依賴於filePattern中的%i-->
            <DefaultRolloverStrategy max="100"/>
        </RollingFile>

        <!--error及更高級別日誌-->
        <RollingFile name="errorFileAppender"
                     fileName="${LOG_HOME}/error.log"
                     filePattern="${LOG_HOME}/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log.gz">
            <!--設置日誌格式-->
            <PatternLayout>
                <pattern>%d %p %C{} [%t] %m%n</pattern>
            </PatternLayout>
            <Policies>
                <!-- 設置日誌文件切分參數 -->
                <!--<OnStartupTriggeringPolicy/>-->
                <!--設置日誌基礎文件大小,超過該大小就觸發日誌文件滾動更新-->
                <SizeBasedTriggeringPolicy size="100 MB"/>
                <!--設置日誌文件滾動更新的時間,依賴於文件命名filePattern的設置-->
                <TimeBasedTriggeringPolicy/>
            </Policies>
            <!--設置日誌的文件個數上限,不設置默認為7個,超過大小後會被覆蓋;依賴於filePattern中的%i-->
            <DefaultRolloverStrategy max="100"/>
        </RollingFile>

        <!--json格式error級別日誌-->
        <RollingFile name="errorJsonAppender"
                     fileName="${LOG_HOME}/error-json.log"
                     filePattern="${LOG_HOME}/error-json-%d{yyyy-MM-dd}-%i.log.gz">
            <JSONLayout compact="true" eventEol="true" locationInfo="true"/>
            <Policies>
                <SizeBasedTriggeringPolicy size="100 MB"/>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
            </Policies>
        </RollingFile>
    </Appenders>

    <Loggers>
        <!-- 根日誌設置 -->
        <Root level="debug">
            <AppenderRef ref="allFileAppender" level="all"/>
            <AppenderRef ref="consoleAppender" level="debug"/>
            <AppenderRef ref="debugFileAppender" level="debug"/>
            <AppenderRef ref="infoFileAppender" level="info"/>
            <AppenderRef ref="warnFileAppender" level="warn"/>
            <AppenderRef ref="errorFileAppender" level="error"/>
            <AppenderRef ref="errorJsonAppender" level="error"/>
        </Root>

        <!--spring日誌-->
        <Logger name="org.springframework" level="debug"/>
        <!--druid數據源日誌-->
        <Logger name="druid.sql.Statement" level="warn"/>
        <!-- mybatis日誌 -->
        <Logger name="com.mybatis" level="warn"/>
        <Logger name="org.hibernate" level="warn"/>
        <Logger name="com.zaxxer.hikari" level="info"/>
        <Logger name="org.quartz" level="info"/>
        <Logger name="com.andya.demo" level="debug"/>
    </Loggers>

</Configuration>

配置參數詳解

Configuration

根節點Configuration中有兩個常用的屬性:status和monitorterval。如:<Configuration status="WARN" monitorInterval="30">

屬性

  1. status:是用於指定log4j的級別;
  2. monitorterval:是用於指定log4j自動重新檢測讀取配置內容的間隔時間,單位為秒(s),最小值為5秒。

Properties

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <properties>
     <property name="LOG_HOME">./service-logs</property>
  </properties>
  <Appenders>
    <File name="MyFile" fileName="${LOG_HOME}/app.log">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
    </File>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="MyFile"/>
    </Root>
  </Loggers>
</Configuration>

變數配置,如模板中的 <property name="LOG_HOME">./service-logs</property>,我們可以配置日誌的路徑。後續日誌存放的前綴路徑即為./service-logs下, <File name="MyFile" fileName="${LOG_HOME}/app.log">中配置了前綴,app.log就會存放在./service-logs下。

Appenders

Console

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <Console name="STDOUT" target="SYSTEM_OUT">
      <PatternLayout pattern="%m%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="STDOUT"/>
    </Root>
  </Loggers>
</Configuration>

  Console節點用於定義輸出控制台的Appender。

屬性

  1. name:用於指定Appender的名稱;
  2. target:用於指定輸出目標,一般是SYSTEM_OUTSYSTEM_ERR,默認是SYSTEM_OUT

節點

  1. PatternLayout:用於指定輸出格式,不設置的話,默認為:%m%n

File

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <File name="MyFile" fileName="logs/app.log">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
    </File>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="MyFile"/>
    </Root>
  </Loggers>
</Configuration>

  File節點用於將日誌輸出到指定文件,一般不用該節點,而使用RollingFile節點。

屬性

  1. name:用於指定Appender的名稱;
  2. fileName:用於指定日誌文件的全路徑;

節點

  1. PatternLayout:用於指定輸出格式,不設置的話,默認為:%m%n

RollingFile

  RollingFile節點用於實現日誌文件更動更新的Appender,當滿足條件(日誌大小、指定時間等)重命名或打包原日誌文件進行歸檔,生成新日誌文件用於日誌寫入。
  我們可以設置ALL、DEBUG、 INFO、 WARN、 ERROR這些級別的RollingFileAppender。

(1)基於大小的滾動策略
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <RollingFile name="RollingFile" fileName="logs/app.log"
                 filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
      <Policies>
        <TimeBasedTriggeringPolicy />
        <SizeBasedTriggeringPolicy size="100 MB"/>
      </Policies>
      <DefaultRolloverStrategy max="10"/>
    </RollingFile>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="RollingFile"/>
    </Root>
  </Loggers>
</Configuration>

  上述模板中,日誌先寫入logs/app.log中,每當文件大小達到100MB時或經過1天,按照在logs/2020-09/目錄下以app-2020-09-09-1.log.gz格式對該日誌進行壓縮重命名並歸檔,並生成新的文件app.log進行日誌寫入。
  其中,filePattern屬性的文件格式中%i就類似於一個整數計數器,受到 <DefaultRolloverStrategy max="10"/>控制,要特別注意的是:當文件個數達到10個的時候會循環覆蓋前面已歸檔的1-10個文件。若不設置該參數,默認為7

(2)基於時間間隔的滾動策略
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <RollingFile name="RollingFile" fileName="logs/app.log"
                 filePattern="logs/$${date:yyyy-MM}/app-%d{yyyy-MM-dd-HH}.log.gz">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
      <Policies>
        <TimeBasedTriggeringPolicy interval="6" modulate="true"/>
      </Policies>
    </RollingFile>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="RollingFile"/>
    </Root>
  </Loggers>
</Configuration>

  上述模板中,日誌先寫入logs/app.log中,每當文件的時間間隔到達6小時(由%d{yyyy-MM-dd-HH}決定,也可以設置成%d{yyyy-MM-dd-HH-mm},則間隔為分鐘級別),觸發rollover操作。
  如上配置設置好後,10點的日誌開始重啟服務,則從11點觸發一次rollover操作,生成2020-09-09-10.log.gz對該日誌進行壓縮重命名並歸檔,並生成新的文件app.log進行日誌寫入;然後,每間隔6小時,則下一次是17點觸發一次,生成2020-09-09-17.log.gz對該日誌進行壓縮重命名並歸檔,並生成新的文件app.log進行日誌寫入。

(3)基於時間間隔和文件大小的滾動策略
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <RollingFile name="RollingFile" fileName="logs/app.log"
                 filePattern="logs/$${date:yyyy-MM}/app-%d{yyyy-MM-dd-HH}-%i.log.gz">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
      <Policies>
        <TimeBasedTriggeringPolicy interval="6" modulate="true"/>
        <SizeBasedTriggeringPolicy size="100 MB"/>
      </Policies>
    </RollingFile>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="RollingFile"/>
    </Root>
  </Loggers>
</Configuration>

  上述模板中,日誌先寫入logs/app.log中,每當文件大小達到100MB或者當時間間隔到達6小時(由%d{yyyy-MM-dd-HH}決定),觸發rollover操作,按照在logs/2020-09/目錄下以app-2020-09-09-1.log.gz格式對該日誌進行壓縮重命名並歸檔,並生成新的文件app.log進行日誌寫入。

屬性

  1. name:用於指定Appender的名稱;
  2. fileName:用於指定日誌文件的全路徑;
  3. filePattern:用於指定分割文件的日誌全路徑(命名規則)。

節點

  1. PatternLayout:用於指定輸出格式,不設置的話,默認為:%m%n
  2. Policies :設置日誌文件切割參數;
  3. SizeBasedTriggeringPolicy:Policies的子節點,用於設置基於日誌文件大小觸發的滾動策略,size屬性用來指定每個分割的日誌文件大小。
  4. TimeBasedTriggeringPolicy:Policies的子節點,用於設置基於時間間隔觸發的滾動策略,interval屬性用於指定滾動時間間隔,默認是1小時,modulate屬性是用於對interval進行偏移調節,默認為false。若為true,則第一次觸發時是第一個小時觸發,後續以interval間隔觸發。
  5. CronTriggeringPolicy:Policies的子節點,用於設置基於Cron表達式觸發的滾動策略。
  6. DefaultRolloverStrategy:設置默認策略設置。

Loggers

節點

  1. Root:用於指定項目的根日誌,level屬性表示日誌輸出級別,子節點AppenderRef用於指定輸出到某個Appender,子節點的ref屬性也就是前面的RollingFile中指定的name名稱,子節點的level也是日誌輸出級別。
  2. Logger :用於指定日誌的形式,指定不同包的日誌級別,level屬性表示日誌輸出級別,name屬性用來指定該Logger所適用的類或者類的全路徑。子節點AppenderRef用於指定日誌輸出到哪個Appender,若沒有指定,默認集成自Root。

參考
log4j2的官網地址