log4j2日志滚动时如何使用旧日志文件的创建日期命名归档文件
解决方案
方法一:修改配置使用创建时间转换符(无代码侵入,推荐)
Log4j2 2.9及以上版本提供了%createTime转换符,用于输出当前待归档日志文件的实际创建时间,替代原配置中代表滚动触发时间的%d即可直接满足需求。
修改后的log4j2.xml配置如下:
<Appenders> <RollingFile name="RollingFile" fileName="${sys:dir}/${sys:file}.log" immediateFlush="true" filePattern="${sys:dir}/${sys:file}.log.%createTime{yyyy_MM_dd.HH_mm_ss}.%i" ignoreExceptions="false"> <PatternLayout pattern="%d{yyyyMMdd-HHmmss.SSS} |%-5p| [%t] [%c] - %-100m %n"/> <Policies> <OnStartupTriggeringPolicy/> </Policies> </RollingFile> </Appenders>
%createTime的时间格式规则和%d完全一致,原有手动触发滚动的代码不需要做任何修改,即可适配主动调用rollover的场景。
方法二:自定义滚动策略(兼容特殊异常场景)
如果修改配置后仍出现时间不符的情况,是因为对应版本OnStartupTriggeringPolicy未正确初始化文件创建时间属性,可以自定义滚动策略,直接读取文件系统存储的文件创建时间来命名归档文件:
- 自定义滚动策略类,继承默认的DefaultRolloverStrategy
import org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy; import org.apache.logging.log4j.core.appender.rolling.RollingFileManager; import org.apache.logging.log4j.core.appender.rolling.RolloverDescription; import org.apache.logging.log4j.core.config.Configuration; import org.apache.logging.log4j.core.config.plugins.Plugin; import org.apache.logging.log4j.core.config.plugins.PluginAttribute; import org.apache.logging.log4j.core.config.plugins.PluginConfiguration; import org.apache.logging.log4j.core.config.plugins.PluginElement; import org.apache.logging.log4j.core.config.plugins.PluginFactory; import java.nio.file.Files; import java.nio.file.attribute.BasicFileAttributes; import java.time.Instant; import java.util.List; import java.util.Arrays; import java.util.zip.Deflater; import java.io.File; @Plugin(name = "CreateTimeRolloverStrategy", category = "Core", printObject = true) public class CreateTimeRolloverStrategy extends DefaultRolloverStrategy { protected CreateTimeRolloverStrategy(int maxIndex, int minIndex, boolean useMax, int compressionLevel, boolean stopCustomActionsOnError, List<Action> customActions, Configuration config) { super(maxIndex, minIndex, useMax, compressionLevel, stopCustomActionsOnError, customActions, config); } @Override public RolloverDescription rollover(RollingFileManager manager) throws SecurityException { try { // 直接读取当前活动日志的系统创建时间,保证时间准确性 BasicFileAttributes attrs = Files.readAttributes(new File(manager.getFileName()).toPath(), BasicFileAttributes.class); Instant fileCreateTime = attrs.creationTime().toInstant(); // 此处可自定义替换filePattern中的时间变量,或直接指定归档文件名 } catch (Exception e) { // 自行补充异常处理逻辑 } return super.rollover(manager); } @PluginFactory public static CreateTimeRolloverStrategy createStrategy( @PluginAttribute("max") final String max, @PluginAttribute("min") final String min, @PluginAttribute("fileIndex") final String fileIndex, @PluginAttribute("compressionLevel") final String compressionLevelStr, @PluginElement("Actions") final Action[] customActions, @PluginAttribute("stopCustomActionsOnError") final String stopCustomActionsOnError, @PluginConfiguration final Configuration config) { // 初始化逻辑直接复用DefaultRolloverStrategy的默认实现即可 int maxIndex = parseInt(max, 7); int minIndex = parseInt(min, 1); boolean useMax = fileIndex == null || "max".equalsIgnoreCase(fileIndex); int compressionLevel = parseInt(compressionLevelStr, Deflater.DEFAULT_COMPRESSION); boolean stopOnError = stopCustomActionsOnError == null || Boolean.parseBoolean(stopCustomActionsOnError); List<Action> actions = customActions == null ? null : Arrays.asList(customActions); return new CreateTimeRolloverStrategy(maxIndex, minIndex, useMax, compressionLevel, stopOnError, actions, config); } }
- 修改log4j2.xml配置,在RollingFile节点下添加自定义滚动策略引用即可:
<RollingFile name="RollingFile" fileName="${sys:dir}/${sys:file}.log" immediateFlush="true" filePattern="${sys:dir}/${sys:file}.log.%d{yyyy_MM_dd.HH_mm_ss}.%i" ignoreExceptions="false"> <PatternLayout pattern="%d{yyyyMMdd-HHmmss.SSS} |%-5p| [%t] [%c] - %-100m %n"/> <Policies> <OnStartupTriggeringPolicy/> </Policies> <!-- 引用自定义滚动策略,max指定最大归档文件数量 --> <CreateTimeRolloverStrategy max="30"/> </RollingFile>
内容的提问来源于stack exchange,提问作者Hasintha Samith Randika
相关产品推荐
相关产品推荐

