Log4j2中%i整数计数器在时间+大小滚动策略下未重置问题
问题场景
使用Log4j2 v2.18.0,要求日志文件每小时或达到100MB时触发滚动,配置如下:
<Appenders> <RollingFile name="APPLICATION" filePattern="/path/to/log.%d{yyyy-MM-dd.HH}.%i.log"> <Policies> <TimeBasedTriggeringPolicy modulate="true"/> <SizeBasedTriggeringPolicy size="100 MB"/> </Policies> </RollingFile> </Appenders>
预期%i计数器会随时间段(每小时)重置,比如每个小时内的日志文件从1开始编号递增,但实际计数器持续全局累加,不会随时间滚动重置。
预期生成的日志文件
/path/to/log.2023-03-22.11.1.log/path/to/log.2023-03-22.12.1.log/path/to/log.2023-03-22.12.2.log
实际生成的日志文件
/path/to/log.2023-03-22.11.1.log/path/to/log.2023-03-22.12.2.log/path/to/log.2023-03-22.12.3.log
官方文档说明(翻译)
RollingFileAppender需要触发策略(TriggeringPolicy)和滚动策略(RolloverStrategy)。触发策略决定何时执行滚动,滚动策略定义滚动的具体逻辑。如果未配置滚动策略,RollingFileAppender默认使用DefaultRolloverStrategy。从log4j-2.5版本开始,可在DefaultRolloverStrategy中配置自定义删除操作,在滚动时执行。从2.8版本开始,如果未配置
fileName属性,会自动使用DirectWriteRolloverStrategy替代DefaultRolloverStrategy。
DirectWriteRolloverStrategy会直接将日志事件写入
filePattern指定格式的文件,不执行文件重命名操作。如果因基于大小的触发策略导致同一时间段内生成多个文件,编号会从1开始递增,但不会随时间滚动重置,而是持续累加。
解决方案
该行为并非bug,而是配置未指定fileName时自动使用DirectWriteRolloverStrategy导致的。要实现按时间段重置计数器的需求,需显式配置fileName并指定使用DefaultRolloverStrategy,修改后的配置如下:
<Appenders> <RollingFile name="APPLICATION" fileName="/path/to/current.log" filePattern="/path/to/log.%d{yyyy-MM-dd.HH}.%i.log"> <Policies> <TimeBasedTriggeringPolicy modulate="true"/> <SizeBasedTriggeringPolicy size="100 MB"/> </Policies> <DefaultRolloverStrategy/> </RollingFile> </Appenders>
添加fileName后,Log4j2会使用DefaultRolloverStrategy,该策略会在每次时间滚动时重置%i计数器,符合预期的文件命名格式。
内容的提问来源于stack exchange,提问作者quietmint

