在Springboot中處理log4j2日志文件過(guò)程
簡(jiǎn)單介紹
日志切割
日志切割指的是將一個(gè)持續(xù)增長(zhǎng)的、龐大的日志文件,按照某種規(guī)則分割成多個(gè)較小的、易于管理的文件。(在本配置中我們將日志按天切割,同時(shí)限制了單個(gè)日志文件不能超過(guò)64MB)
效果如圖:
切割策略有兩個(gè),每天零點(diǎn)會(huì)將昨天的日志文件加日期保存然后生成一個(gè)新的日志文件,當(dāng)天如果單個(gè)日志文件超出規(guī)定(例如本配置的64MB),會(huì)自動(dòng)將此日志文件加日期保存并生成一個(gè)新的日志文件

日志分離
日志分離指的是將不同種類、不同級(jí)別或來(lái)自不同模塊的日志信息,輸出到不同的、獨(dú)立的日志文件中。
效果如圖:
日志被根據(jù)不同級(jí)別分層保存

日志清理
日志清理指的是自動(dòng)刪除舊的、不再需要的日志歸檔文件,以防止日志文件無(wú)限制地占用磁盤(pán)空間,最終導(dǎo)致磁盤(pán)寫(xiě)滿。
這是生產(chǎn)環(huán)境中至關(guān)重要的一環(huán)。(比如本配置的清理就是會(huì)刪除超過(guò)N(比如Info30天,Warn60天,Error90天)天的日志歸檔文件以及每個(gè)類型的日志文件總大小不超過(guò)某個(gè)GB的大小(比如Info6GB,Warn3GB,Error2GB))
如何在SpringBoot項(xiàng)目中配置使用
第一步,導(dǎo)入如下依賴到pom.xml文件當(dāng)中
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>第二步,在yaml文件中添加如下配置
logging: config: classpath:log4j2.xml
第三步,將xml文件放到resource目錄下,下次啟動(dòng)項(xiàng)目,日志會(huì)自動(dòng)被記錄到logs目錄(這個(gè)目錄會(huì)在項(xiàng)目啟動(dòng)時(shí)自動(dòng)生成)并分離清洗

xml文件名: log4j2.xml
文件代碼:
<Configuration status="WARN">
<Properties>
<Property name="LOG_PATH">logs</Property>
<Property name="APP_NAME">app</Property>
<Property name="FILE_SIZE">64MB</Property>
<Property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p [%t] %c{1.} [%X{traceId:-}] - %m%n%ex</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${LOG_PATTERN}"/>
</Console>
<RollingFile name="InfoFile" fileName="${LOG_PATH}/${APP_NAME}-info.log" filePattern="${LOG_PATH}/$${date:yyyy-MM}/${APP_NAME}-info-%d{yyyy-MM-dd}-%i.log">
<Filters>
<LevelMatchFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="${FILE_SIZE}"/>
</Policies>
<DefaultRolloverStrategy>
<max>64</max>
<Delete basePath="${LOG_PATH}" maxDepth="2">
<IfFileName glob="*/app-info*.log"/>
<IfLastModified age="30d"/>
</Delete>
<Delete basePath="${LOG_PATH}" maxDepth="2">
<IfFileName glob="*/app-info*.log"/>
<IfAccumulatedFileSize exceeds="6GB"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<RollingFile name="WarnFile" fileName="${LOG_PATH}/${APP_NAME}-warn.log" filePattern="${LOG_PATH}/$${date:yyyy-MM}/${APP_NAME}-warn-%d{yyyy-MM-dd}-%i.log">
<Filters>
<LevelMatchFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="${FILE_SIZE}"/>
</Policies>
<DefaultRolloverStrategy>
<max>64</max>
<Delete basePath="${LOG_PATH}" maxDepth="2">
<IfFileName glob="*/app-warn*.log"/>
<IfLastModified age="60d"/>
</Delete>
<Delete basePath="${LOG_PATH}" maxDepth="2">
<IfFileName glob="*/app-warn*.log"/>
<IfAccumulatedFileSize exceeds="3GB"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<RollingFile name="ErrorFile" fileName="${LOG_PATH}/${APP_NAME}-error.log" filePattern="${LOG_PATH}/$${date:yyyy-MM}/${APP_NAME}-error-%d{yyyy-MM-dd}-%i.log">
<Filters>
<LevelMatchFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="${FILE_SIZE}"/>
</Policies>
<DefaultRolloverStrategy>
<max>64</max>
<Delete basePath="${LOG_PATH}" maxDepth="2">
<IfFileName glob="*/app-error*.log"/>
<IfLastModified age="90d"/>
</Delete>
<Delete basePath="${LOG_PATH}" maxDepth="2">
<IfFileName glob="*/app-error*.log"/>
<IfAccumulatedFileSize exceeds="2GB"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<RollingFile name="DebugFile" fileName="${LOG_PATH}/${APP_NAME}-debug.log" filePattern="${LOG_PATH}/$${date:yyyy-MM}/${APP_NAME}-debug-%d{yyyy-MM-dd}-%i.log">
<Filters>
<LevelMatchFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="${FILE_SIZE}"/>
</Policies>
<DefaultRolloverStrategy>
<max>64</max>
<Delete basePath="${LOG_PATH}" maxDepth="2">
<IfFileName glob="*/app-debug*.log"/>
<IfLastModified age="7d"/>
</Delete>
<Delete basePath="${LOG_PATH}" maxDepth="2">
<IfFileName glob="*/app-debug*.log"/>
<IfAccumulatedFileSize exceeds="5GB"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="org.springframework" level="info" additivity="false">
<AppenderRef ref="Console"/>
<AppenderRef ref="InfoFile"/>
<AppenderRef ref="WarnFile"/>
<AppenderRef ref="ErrorFile"/>
</Logger>
<Logger name="org.hibernate" level="warn"/>
<Root level="info">
<AppenderRef ref="Console"/>
<AppenderRef ref="InfoFile"/>
<AppenderRef ref="WarnFile"/>
<AppenderRef ref="ErrorFile"/>
</Root>
</Loggers>
</Configuration>實(shí)現(xiàn)原理
日志切割
Appender 就是日志的輸出目的地。Appender 中的 RollingFile都設(shè)置了兩種觸發(fā)策略,它們之間是“或”的關(guān)系,只要滿足任一條件,就會(huì)觸發(fā)日志切割
<TimeBasedTriggeringPolicy/>基于時(shí)間滾動(dòng),每天零點(diǎn)自動(dòng)生成新的日志文件<SizeBasedTriggeringPolicy size="${FILE_SIZE}"/>基于文件大小的觸發(fā)策略。
參數(shù) ${FILE_SIZE}被定義為 64MB。
這意味著,即使在同一天內(nèi),只要當(dāng)前正在寫(xiě)入的日志文件大小達(dá)到 64MB,也會(huì)立即觸發(fā)切割,并生成一個(gè)新的日志文件 。
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="${FILE_SIZE}"/>
</Policies>日志的分離
可以看到,在Appenders中RollingFile被分為了四種,分別是Info,Warn,Error,Debug級(jí)別的文件
當(dāng)日志文件被切割后,其歸檔文件的命名和存放位置由 filePattern屬性精確控制:
filePattern="${LOG_PATH}/$${date:yyyy-MM}/${APP_NAME}-info-%d{yyyy-MM-dd}-%i.log.gz"這個(gè)配置實(shí)現(xiàn)了以下效果:
- 按月份歸檔:
$${date:yyyy-MM}會(huì)在logs目錄下自動(dòng)創(chuàng)建像2025-03這樣的子文件夾,將當(dāng)月所有的歸檔日志文件放入其中,使目錄結(jié)構(gòu)非常清晰 。。 - 索引區(qū)分:當(dāng)同一天內(nèi)因文件大小觸發(fā)多次切割時(shí),
%i是一個(gè)從1開(kāi)始遞增的索引號(hào),用于區(qū)分同一天產(chǎn)生的不同日志文件,例如會(huì)產(chǎn)生app-info-2025-03-18-1.log,app-info-2025-03-18-2.log等文件。
日志清理
日志清理有三個(gè)策略
<max>64</max>在這里表示:當(dāng)天最多可以生成 64 個(gè)歸檔日志文件(例如 app-info-2025-10-15-1.log.gz到 app-info-2025-10-15-64.log.gz)。
當(dāng)同一天內(nèi)的第 65 次滾動(dòng)觸發(fā)時(shí),最早的那個(gè)文件(如 ...-1.log.gz)將會(huì)被刪除 。
<IfFileName glob="*/app-info*.log"/> <IfLastModified age="30d"/>
這個(gè)代表如果超過(guò)30天會(huì)把info類型的最舊日志刪除
<IfFileName glob="*/app-info*.log"/> <IfAccumulatedFileSize exceeds="6GB"/>
這個(gè)代表如果超過(guò)6GB會(huì)把info類型的最舊日志刪除
<DefaultRolloverStrategy>
<max>64</max>
<Delete basePath="${LOG_PATH}" maxDepth="2">
<IfFileName glob="*/app-info*.log"/>
<IfLastModified age="30d"/>
</Delete>
<Delete basePath="${LOG_PATH}" maxDepth="2">
<IfFileName glob="*/app-info*.log"/>
<IfAccumulatedFileSize exceeds="6GB"/>
</Delete>
</DefaultRolloverStrategy>總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- SpringBoot LogbackvsLog4j2配置與性能測(cè)試對(duì)比分析
- SpringBoot項(xiàng)目使用Log4j2+SLF4J構(gòu)建日志的方法步驟
- 一文帶你搞定SpringBoot Log4j2日志配置文件
- SpringBoot將logback替換成log4j2的操作步驟
- SpringBoot使用log4j2將日志記錄到文件及自定義數(shù)據(jù)庫(kù)的配置方法
- SpringBoot項(xiàng)目整合Log4j2實(shí)現(xiàn)自定義日志打印失效問(wèn)題解決
- SpringBoot整合Log4j2實(shí)現(xiàn)自定義日志打印失效的原因及解決
- SpringBoot配置log4j2的實(shí)現(xiàn)示例
相關(guān)文章
Mybatis中攔截器的簡(jiǎn)單實(shí)現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于Mybatis中攔截器的簡(jiǎn)單實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Mybatis具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08
java實(shí)現(xiàn)在原有日期時(shí)間上加幾個(gè)月或幾天
這篇文章主要介紹了java實(shí)現(xiàn)在原有日期時(shí)間上加幾個(gè)月或幾天,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10
Java開(kāi)發(fā)常見(jiàn)錯(cuò)誤之?dāng)?shù)值計(jì)算精度和舍入問(wèn)題詳析
除了使用Double保存浮點(diǎn)數(shù)可能帶來(lái)精度問(wèn)題外,更匪夷所思的是這種精度問(wèn)題,下面這篇文章主要給大家介紹了關(guān)于Java開(kāi)發(fā)常見(jiàn)錯(cuò)誤之?dāng)?shù)值計(jì)算精度和舍入問(wèn)題的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-11-11
SpringBoot使用PropertiesLauncher加載外部jar包
這篇文章主要介紹了SpringBoot使用PropertiesLauncher加載外部jar包,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07
shenyu怎么處理sign鑒權(quán)前置到網(wǎng)關(guān)
這篇文章主要為大家介紹了shenyu怎么處理sign鑒權(quán)前置到網(wǎng)關(guān)方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
Springboot框架實(shí)現(xiàn)自動(dòng)裝配詳解
在使用springboot時(shí),很多配置我們都沒(méi)有做,都是springboot在幫我們完成,這很大一部分歸功于springboot自動(dòng)裝配。本文將詳細(xì)為大家講解SpringBoot的自動(dòng)裝配原理,需要的可以參考一下2022-08-08
spring事務(wù)之事務(wù)掛起和事務(wù)恢復(fù)源碼解讀
這篇文章主要介紹了spring事務(wù)之事務(wù)掛起和事務(wù)恢復(fù)源碼解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11

