Log4j2 Cron与Size触发策略组合日志日期异常及轮转停止问题
Log4j2日志轮转问题解决方案
使用的Log4j2依赖
<properties> <jdkVersion>1.8</jdkVersion> <log4jVersion>2.17.1</log4jVersion> </properties> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-web</artifactId> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> </dependency>
Log4j2配置
<Properties> <Property name="baseDir">${env:APP_HOME}/logs/${web:contextPath}</Property> <Property name="filename">${baseDir}/DeviceManagement.log</Property> <Property name="filePattern">${baseDir}/DeviceManagement-%d{yyyy-MM-dd}-%i.log</Property> <Property name="layoutPattern">[%5p][%t][%c.%M():%L][%d{yy/MM/dd HH:mm:ss.SSS}][%4r]%n%m%n</Property> </Properties> <Appenders> <Appender type="Console" name="STDOUT"> <Layout type="PatternLayout" pattern="${layoutPattern}"/> </Appender> <Appender type="RollingFile" name="ROLLING_FILE" fileName="${filename}" filePattern="${filePattern}"> <Layout type="PatternLayout" pattern="${layoutPattern}"/> <Policies> <CronTriggeringPolicy schedule="0 0 0 * * ?"/> <SizeBasedTriggeringPolicy size="5 MB"/> </Policies> <DefaultRolloverStrategy max="20"> <Delete basePath="${baseDir}" maxDepth="2"> <IfFileName glob="{DeviceLog/*.log,DeviceManagement-*.log}"/> <IfLastModified age="P60D"> <IfAny> <IfAccumulatedFileSize exceeds="100 MB" /> <IfAccumulatedFileCount exceeds="60" /> </IfAny> </IfLastModified> </Delete> </DefaultRolloverStrategy> </Appender> </Appenders>
预期结果
日志文件应每日午夜轮转,文件名包含当日日期;基于大小的轮转每日最多生成20个文件。
问题现象
日期轮转后文件名显示前一天日期而非当日日期;且基于大小的轮转在索引达到20后停止继续轮转,具体文件列表如下:
2024/03/19 AM 02:26 5,246,621 DeviceManagement-2024-03-18-1.log <----3月19日02:26轮转,文件名应为2024-03-19却显示2024-03-18。 2024/03/19 AM 02:54 5,242,886 DeviceManagement-2024-03-18-2.log 2024/03/19 AM 03:21 5,242,887 DeviceManagement-2024-03-18-3.log 2024/03/19 AM 03:50 5,248,627 DeviceManagement-2024-03-18-4.log 2024/03/19 AM 04:20 5,243,058 DeviceManagement-2024-03-18-5.log 2024/03/19 AM 04:50 5,243,757 DeviceManagement-2024-03-18-6.log 2024/03/19 AM 05:21 5,245,418 DeviceManagement-2024-03-18-7.log 2024/03/19 AM 05:52 5,247,493 DeviceManagement-2024-03-18-8.log 2024/03/19 AM 06:25 5,243,024 DeviceManagement-2024-03-18-9.log 2024/03/19 AM 06:56 5,243,052 DeviceManagement-2024-03-18-10.log 2024/03/19 AM 07:29 5,243,677 DeviceManagement-2024-03-18-11.log 2024/03/19 AM 08:02 5,245,473 DeviceManagement-2024-03-18-12.log 2024/03/19 AM 08:31 5,243,077 DeviceManagement-2024-03-18-13.log 2024/03/19 AM 08:54 5,243,030 DeviceManagement-2024-03-18-14.log 2024/03/19 AM 09:07 5,243,012 DeviceManagement-2024-03-18-15.log 2024/03/19 AM 09:20 5,243,273 DeviceManagement-2024-03-18-16.log 2024/03/19 AM 09:43 5,243,066 DeviceManagement-2024-03-18-17.log 2024/03/19 AM 10:06 5,249,359 DeviceManagement-2024-03-18-18.log 2024/03/19 AM 10:28 5,243,121 DeviceManagement-2024-03-18-19.log 2024/03/19 AM 10:47 5,242,932 DeviceManagement-2024-03-18-20.log <-----10:47达到索引20后停止轮转至索引1 2024/03/20 AM 02:11 151,699 DeviceManagement.log <-----当前活跃文件
解决方案
1. 日期轮转文件名错误问题
默认%d在filePattern中使用的是日志事件发生时间,而非轮转触发时间。午夜轮转时,文件最后一条日志属于前一天,导致文件名用了前一天日期。
修改filePattern,给%d添加{ROLLING_FILE}标记,指定使用轮转触发时间:
<Property name="filePattern">${baseDir}/DeviceManagement-%d{yyyy-MM-dd}{ROLLING_FILE}-%i.log</Property>
2. 大小轮转索引到20后停止问题
当前DefaultRolloverStrategy的max="20"是限制所有历史文件总数,而非每日文件数。要实现每日最多20个文件,需调整触发策略和滚动规则:
步骤1:替换触发策略
用TimeBasedTriggeringPolicy替代CronTriggeringPolicy,更适配时间轮转场景,设置interval="1"表示每日轮转:
<Policies> <TimeBasedTriggeringPolicy interval="1"/> <SizeBasedTriggeringPolicy size="5 MB"/> </Policies>
步骤2:调整滚动策略
修改DefaultRolloverStrategy,添加fileIndex="nomax"取消全局文件数限制,同时优化Delete规则,按日期分组保留最多20个文件:
<DefaultRolloverStrategy fileIndex="nomax"> <Delete basePath="${baseDir}" maxDepth="2"> <IfFileName glob="DeviceManagement-*.log"/> <!-- 按每日分组,保留最多20个文件 --> <IfAccumulatedFileCount exceeds="20"> <IfFileName glob="DeviceManagement-${date:yyyy-MM-dd}-*.log"/> </IfAccumulatedFileCount> <!-- 保留60天内文件,超过则触发删除规则 --> <IfLastModified age="P60D"> <IfAny> <IfAccumulatedFileSize exceeds="100 MB" /> <IfAccumulatedFileCount exceeds="60" /> </IfAny> </IfLastModified> </Delete> </DefaultRolloverStrategy>
最终完整配置
<Properties> <Property name="baseDir">${env:APP_HOME}/logs/${web:contextPath}</Property> <Property name="filename">${baseDir}/DeviceManagement.log</Property> <Property name="filePattern">${baseDir}/DeviceManagement-%d{yyyy-MM-dd}{ROLLING_FILE}-%i.log</Property> <Property name="layoutPattern">[%5p][%t][%c.%M():%L][%d{yy/MM/dd HH:mm:ss.SSS}][%4r]%n%m%n</Property> </Properties> <Appenders> <Appender type="Console" name="STDOUT"> <Layout type="PatternLayout" pattern="${layoutPattern}"/> </Appender> <Appender type="RollingFile" name="ROLLING_FILE" fileName="${filename}" filePattern="${filePattern}"> <Layout type="PatternLayout" pattern="${layoutPattern}"/> <Policies> <TimeBasedTriggeringPolicy interval="1"/> <SizeBasedTriggeringPolicy size="5 MB"/> </Policies> <DefaultRolloverStrategy fileIndex="nomax"> <Delete basePath="${baseDir}" maxDepth="2"> <IfFileName glob="DeviceManagement-*.log"/> <IfAccumulatedFileCount exceeds="20"> <IfFileName glob="DeviceManagement-${date:yyyy-MM-dd}-*.log"/> </IfAccumulatedFileCount> <IfLastModified age="P60D"> <IfAny> <IfAccumulatedFileSize exceeds="100 MB" /> <IfAccumulatedFileCount exceeds="60" /> </IfAny> </IfLastModified> </Delete> </DefaultRolloverStrategy> </Appender> </Appenders>
内容的提问来源于stack exchange,提问作者Bruce
相关产品推荐
相关产品推荐

