0%

log4j2日志文件滚动

log4j2日志文件滚动

Appender在log4j2中有很多实现类,如ConsoleAppender(插件名称为Console)、FileAppender(插件名称为File)、RollingFileAppender(插件名称为RollingFile)等,在实际的项目中通常使用的都是RollingFileAppender,也就是日志文件滚动更新的Appender

1
2
3
4
5
6
7
8
9
<RollingFile name="file" fileName="/data/log/app.log"
filePattern="/data/log/app.log.%d{yyyyMMdd}.%i.bz2">
<PatternLayout charset="UTF-8" pattern="[%-5p %d{yyyy-MM-dd HH:mm:ss.SSS}] %l [%m]%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="1024 MB"/>
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>

其滚动依赖于TriggeringPolicy(触发策略)和RolloverStrategy(滚动更新策略)

TriggeringPolicy

TriggeringPolicy为触发策略,决定了何时触发日志文件的滚动。常见策略有CronTriggeringPolicy、OnStartupTriggeringPolicy、SizeBasedTriggeringPolicy、TimeBasedTriggeringPolicy、CompositeTriggeringPolicy

CronTriggeringPolicy

CronTriggeringPolicy是基于Cron表达式来进行触发的

1
2
<!-- 根据cron来进行触发 -->
<CronTriggeringPolicy schedule="0 0 0 * * ?"/>

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static CronTriggeringPolicy createPolicy(@PluginConfiguration final Configuration configuration,
@PluginAttribute("evaluateOnStartup") final String evaluateOnStartup,
@PluginAttribute("schedule") final String schedule) {
// private static final String defaultSchedule = "0 0 0 * * ?";
CronExpression cronExpression;
final boolean checkOnStartup = Boolean.parseBoolean(evaluateOnStartup);
if (schedule == null) {
LOGGER.info("No schedule specified, defaulting to Daily");
cronExpression = getSchedule(defaultSchedule);
} else {
cronExpression = getSchedule(schedule);
if (cronExpression == null) {
LOGGER.error("Invalid expression specified. Defaulting to Daily");
cronExpression = getSchedule(defaultSchedule);
}
}
return new CronTriggeringPolicy(cronExpression, checkOnStartup, configuration);
}

该策略与SizeBasedTriggeringPolicy、TimeBasedTriggeringPolicy不同,不管日志是否写入,而是新开启一个定时线程来进行管理,而不是根据isTriggeringEvent方法来判断是否触发的

OnStartupTriggeringPolicy

OnStartupTriggeringPolicy是在JVM启动时触发

SizeBasedTriggeringPolicy

SizeBasedTriggeringPolicy是基于文件大小触发

1
2
<!-- 当达到指定size时触发滚动操作,可以用KB/MB/GB作为单位,默认是10M -->
<SizeBasedTriggeringPolicy size="1024 MB"/>

代码

1
2
3
4
5
public static SizeBasedTriggeringPolicy createPolicy(@PluginAttribute("size") final String size) {
// private static final long MAX_FILE_SIZE = 10 * 1024 * 1024; // let 10 MB the default max size
final long maxSize = size == null ? MAX_FILE_SIZE : FileSize.parse(size, MAX_FILE_SIZE);
return new SizeBasedTriggeringPolicy(maxSize);
}

在日志写入时会触发isTriggeringEvent方法来判断是否需要滚动

TimeBasedTriggeringPolicy

TimeBasedTriggeringPolicy是基于时间触发,与日志filePattern中的时间有关,当日志文件名中的pattern不再符合filePattern中的pattern时,就会触发滚动操作。如我配置的filePattern="/data/log/app.log.%d{yyyyMMdd},文件名为app.log.20240830.log,当时间到达20240831时,就会触发滚动操作

1
2
3
4
5
<!-- 
interval 默认1,时间间隔,单位是filePattern中设置的最小时间粒度,如我上述配置%d{yyyyMMdd},时间粒度就是天,每天触发一次
modulate 默认false,指明是否对interval进行调节。若modulate为true,会以0为开始对interval进行偏移计算
-->
<TimeBasedTriggeringPolicy/>

代码

1
2
3
4
5
6
7
8
public static TimeBasedTriggeringPolicy createPolicy(
@PluginAttribute("interval") final String interval,
@PluginAttribute("modulate") final String modulate) {
return newBuilder()
.withInterval(Integers.parseInt(interval, 1))
.withModulate(Boolean.parseBoolean(modulate))
.build();
}

在日志写入时会触发isTriggeringEvent方法来判断是否需要滚动

CompositeTriggeringPolicy

CompositeTriggeringPolicy是组合多个策略进行触发

1
2
3
4
5
<!-- 复合策略,将多个策略放到Policies中,满足一个条件就会触发滚动 -->
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="1024 MB"/>
</Policies>

RolloverStrategy

RolloverStrategy为滚动更新策略,决定了当触发日志文件的滚动时,如何进行文件的滚动。log4j2提供了默认的DefaultRolloverStrategy

DefaultRolloverStrategy

DefaultRolloverStrategy是提供的默认更新策略,即使不进行配置,也会使用该策略,默认max为7

1
2
3
4
<!-- 默认max为7,表示最大保留的日志个数,超过则删除旧的日志
与filePattern中的%i配置配合,如果没有使用%i则该max配置无效
-->
<DefaultRolloverStrategy max="1000"/>

欢迎关注我的其它发布渠道