在Springboot中处理log4j2日志文件
简单介绍
日志切割
日志切割指的是将一个持续增长的、庞大的日志文件,按照某种规则分割成多个较小的、易于管理的文件。(在本配置中我们将日志按天切割,同时限制了单个日志文件不能超过64MB)
效果如图:
切割策略有两个,每天零点会将昨天的日志文件加日期保存然后生成一个新的日志文件,当天如果单个日志文件超出规定(例如本配置的64MB),会自动将此日志文件加日期保存并生成一个新的日志文件
日志分离
日志分离指的是将不同种类、不同级别或来自不同模块的日志信息,输出到不同的、独立的日志文件中。
效果如图:
日志被根据不同级别分层保存
日志清理
日志清理指的是自动删除旧的、不再需要的日志归档文件,以防止日志文件无限制地占用磁盘空间,最终导致磁盘写满。这是生产环境中至关重要的一环。(比如本配置的清理就是会删除超过N(比如Info30天,Warn60天,Error90天)天的日志归档文件以及每个类型的日志文件总大小不超过某个GB的大小(比如Info6GB,Warn3GB,Error2GB))
如何在SpringBoot项目中配置使用
第一步,导入如下依赖到pom.xml文件当中
<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目录下,下次启动项目,日志会自动被记录到logs目录(这个目录会在项目启动时自动生成)并分离清洗
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>
实现原理:
日志切割
Appender 就是日志的输出目的地。Appender 中的 RollingFile
都设置了两种触发策略,它们之间是“或”的关系,只要满足任一条件,就会触发日志切割
<TimeBasedTriggeringPolicy/>
基于时间滚动,每天零点自动生成新的日志文件
<SizeBasedTriggeringPolicy size="${FILE_SIZE}"/>
基于文件大小的触发策略。参数 ${FILE_SIZE}
被定义为 64MB
。这意味着,即使在同一天内,只要当前正在写入的日志文件大小达到 64MB,也会立即触发切割,并生成一个新的日志文件 。
<Policies><TimeBasedTriggeringPolicy/><SizeBasedTriggeringPolicy size="${FILE_SIZE}"/></Policies>
日志的分离
可以看到,在Appenders中RollingFile被分为了四种,分别是Info,Warn,Error,Debug级别的文件
当日志文件被切割后,其归档文件的命名和存放位置由 filePattern
属性精确控制:
filePattern="${LOG_PATH}/$${date:yyyy-MM}/${APP_NAME}-info-%d{yyyy-MM-dd}-%i.log.gz"
这个配置实现了以下效果:
- 按月份归档:
$${date:yyyy-MM}
会在logs
目录下自动创建像2025-03
这样的子文件夹,将当月所有的归档日志文件放入其中,使目录结构非常清晰 。。 - 索引区分:当同一天内因文件大小触发多次切割时,
%i
是一个从1开始递增的索引号,用于区分同一天产生的不同日志文件,例如会产生app-info-2025-03-18-1.log
,app-info-2025-03-18-2.log
等文件。
日志清理
日志清理有三个策略
1.<max>64</max>
在这里表示:当天最多可以生成 64 个归档日志文件(例如 app-info-2025-10-15-1.log.gz
到 app-info-2025-10-15-64.log.gz
)。当同一天内的第 65 次滚动触发时,最早的那个文件(如 ...-1.log.gz
)将会被删除 。
- <IfFileName glob="*/app-info*.log"/>
<IfLastModified age="30d"/>
这个代表如果超过30天会把info类型的最旧日志删除
- <IfFileName glob="*/app-info*.log"/>
<IfAccumulatedFileSize exceeds="6GB"/>
这个代表如果超过6GB会把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>