Log4j2 DirectWriteRolloverStrategy带%i填充时卡在第100个日志文件
Log4j滚动日志卡在第100个文件的问题排查与解决
问题现象
使用Log4j 2.17.2配置滚动日志如下:
<RollingFile name="ROLLING_FILE"> <FilePattern>logs/mylog.%010i.log.gz</FilePattern> <DirectWriteRolloverStrategy maxFiles="50"/> <Policies> <SizeBasedTriggeringPolicy size="1 KB"/> </Policies> <PatternLayout> <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p %c [%t] (..%-C{3}) %x | %m%n</Pattern> <Header>${sys:log4j.mylog.name} ${sys:log4j.mylog.version} build-${sys:log4j.mylog.build.number}%n</Header> </PatternLayout> <Append>true</Append> </RollingFile>
通过以下代码循环生成日志测试滚动:
for (; ; ) { log.error("errorrrrr"); }
发现日志滚动到第100个文件后就停滞,无法生成后续文件;但移除%i的数字填充格式(改为logs/mylog.%i.log.gz)后,滚动功能完全正常。
问题根因
这是Log4j 2.17.2的已知Bug:当FilePattern中使用带固定位数填充的%010i格式时,滚动策略的序号处理逻辑存在异常,导致序号增长到100后无法继续生成新文件。该问题在Log4j 2.20.0版本中已被修复。
解决方案与需求适配
1. 版本升级(最优方案)
将Log4j版本升级至2.20.0及以上,即可保留原配置的数字填充格式,同时解决滚动停滞问题。
2. 临时配置调整(无法升级时)
若暂时无法升级版本,可修改FilePattern去掉数字填充:
<FilePattern>logs/mylog.%i.log.gz</FilePattern>
此方式牺牲了文件名序号的位数对齐,但能保证滚动功能正常运行。
3. 满足补充需求
- 按顺序检索日志:无论是否使用数字填充,日志文件名中的
%i序号都是递增的,按序号从小到大即可顺序检索。 - 限制总日志数:当前配置中
DirectWriteRolloverStrategy的maxFiles="50"已实现该限制,文件数量达到阈值后,最早的归档文件会被自动删除。 - 最新日志存储:
- 若要将最新日志存在
mylog.log,只需在RollingFile节点中添加<File>logs/mylog.log</File>,滚动时当前日志会被重命名为归档格式,同时新建mylog.log存储最新日志。 - 若需符号链接指向最新日志,Log4j本身不支持自动创建,需结合操作系统脚本或定时任务实现,将最新的归档文件链接为
mylog.log。
- 若要将最新日志存在
验证结果
升级至Log4j 2.20.0后,使用原带数字填充的配置测试,日志滚动可正常生成超过100个文件,无停滞问题。
内容的提问来源于stack exchange,提问作者bodrin
相关产品推荐
相关产品推荐

