關注微信公眾號: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>
這邊要注意的是:
- 在引入log4j2時,需要排除掉Logback日誌框架的依賴即。
<artifactId>spring-boot-starter-logging</artifactId>
- 如果是
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
中進行訪問路徑的配置。
示例如下:
- log4j2.xml部署位置
在程式碼工程中的src/main/resources目錄下放入配置檔案。 - 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路徑。
- 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
- 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">
屬性
status
:是用於指定log4j的級別;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。
屬性
name
:用於指定Appender的名稱;target
:用於指定輸出目標,一般是SYSTEM_OUT
或SYSTEM_ERR
,預設是SYSTEM_OUT
;
節點
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
節點。
屬性
name
:用於指定Appender的名稱;fileName
:用於指定日誌檔案的全路徑;
節點
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
進行日誌寫入。
屬性
name
:用於指定Appender的名稱;fileName
:用於指定日誌檔案的全路徑;filePattern
:用於指定分割檔案的日誌全路徑(命名規則)。
節點
PatternLayout
:用於指定輸出格式,不設定的話,預設為:%m%n
;Policies
:設定日誌檔案切割引數;SizeBasedTriggeringPolicy
:Policies的子節點,用於設定基於日誌檔案大小觸發的滾動策略,size
屬性用來指定每個分割的日誌檔案大小。TimeBasedTriggeringPolicy
:Policies的子節點,用於設定基於時間間隔觸發的滾動策略,interval
屬性用於指定滾動時間間隔,預設是1小時,modulate
屬性是用於對interval進行偏移調節,預設為false。若為true,則第一次觸發時是第一個小時觸發,後續以interval間隔觸發。CronTriggeringPolicy
:Policies的子節點,用於設定基於Cron表示式觸發的滾動策略。DefaultRolloverStrategy
:設定預設策略設定。
Loggers
節點
Root
:用於指定專案的根日誌,level
屬性表示日誌輸出級別,子節點AppenderRef
用於指定輸出到某個Appender,子節點的ref
屬性也就是前面的RollingFile中指定的name名稱,子節點的level
也是日誌輸出級別。Logger
:用於指定日誌的形式,指定不同包的日誌級別,level
屬性表示日誌輸出級別,name
屬性用來指定該Logger所適用的類或者類的全路徑。子節點AppenderRef
用於指定日誌輸出到哪個Appender,若沒有指定,預設整合自Root。