You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Log4j2 2.20.2:XML配置下如何捕获日志滚动事件并实现定时滚动

在Log4j2 2.20.2中捕获日志滚动事件并实现定时滚动

一、先修复每分钟滚动的问题

你自定义的XXXX_TriggeringPolicy存在逻辑瑕疵,导致滚动不生效,可按以下方式调整,或直接使用官方内置策略简化实现:

1. 修正自定义触发策略的逻辑

调整initialize和isTriggeringEvent方法,确保时间计算准确:

@Override
public void initialize(final RollingFileManager aManager) {
    this.manager = aManager;
    long current = aManager.getFileTime();
    if (current == 0) {
        current = System.currentTimeMillis();
    }
    PatternProcessor patternProcessor = aManager.getPatternProcessor();
    patternProcessor.setTimeBased(true);
    // 根据filePattern的分钟粒度计算下一次滚动时间
    nextRolloverMillis = patternProcessor.getNextTime(current, interval, modulate);
    // 按需添加随机延迟
    if (maxRandomDelayMillis > 0) {
        nextRolloverMillis += ThreadLocalRandom.current().nextLong(0, maxRandomDelayMillis + 1);
    }
}

@Override
public boolean isTriggeringEvent(final LogEvent event) {
    final long nowMillis = event.getTimeMillis();
    if (nowMillis >= nextRolloverMillis) {
        PatternProcessor patternProcessor = manager.getPatternProcessor();
        // 用当前事件时间计算下一次滚动点,避免时间偏差
        nextRolloverMillis = patternProcessor.getNextTime(nowMillis, interval, modulate);
        if (maxRandomDelayMillis > 0) {
            nextRolloverMillis += ThreadLocalRandom.current().nextLong(0, maxRandomDelayMillis + 1);
        }
        patternProcessor.setCurrentFileTime(nowMillis);
        return true;
    }
    return false;
}

2. 简化方案:使用官方TimeBasedTriggeringPolicy

无需自定义触发策略,官方组件已支持按时间粒度滚动,结合你的filePattern(分钟级),配置如下即可实现每分钟滚动:

<Policies>
    <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
</Policies>

二、捕获日志滚动事件的可靠方法

要在滚动完成后执行业务逻辑,推荐以下两种方式:

方法1:自定义RolloverStrategy

继承DefaultRolloverStrategy,在滚动完成后注入业务逻辑:

@Plugin(name = "CustomRolloverStrategy", category = Core.CATEGORY_NAME, printObject = true)
public class CustomRolloverStrategy extends DefaultRolloverStrategy {

    protected CustomRolloverStrategy(Builder builder) {
        super(builder);
    }

    @Override
    public RolloverResult rollover(RollingFileManager manager) {
        // 先执行默认滚动流程
        RolloverResult result = super.rollover(manager);
        // 滚动成功后执行业务逻辑
        if (result.getSuccess()) {
            String rolledFilePath = manager.getPatternProcessor().getCurrentFileName();
            // 示例:处理滚动后的文件(压缩、上传等)
            handleRolledFile(rolledFilePath);
        }
        return result;
    }

    private void handleRolledFile(String filePath) {
        System.out.println("日志文件已滚动:" + filePath);
        // 这里添加你的业务逻辑
    }

    @PluginBuilderFactory
    public static Builder newBuilder() {
        return new Builder();
    }

    public static class Builder extends DefaultRolloverStrategy.Builder<Builder> {
        @Override
        public CustomRolloverStrategy build() {
            return new CustomRolloverStrategy(this);
        }
    }
}

在XML配置中指定该策略:

<RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/app-%d{yyyy-MM-dd-HH-mm}.log">
    <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
    </PatternLayout>
    <Policies>
        <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
    </Policies>
    <CustomRolloverStrategy/>
</RollingFile>

方法2:添加RollingFileManager监听器

在应用初始化完成后,给滚动文件管理器添加监听器,监听滚动前后事件:

// 获取目标Appender
RollingFileAppender appender = (RollingFileAppender) LogManager.getContext(false)
        .getConfiguration().getAppender("RollingFile");
// 获取滚动管理器
RollingFileManager manager = appender.getManager();
// 添加滚动监听器
manager.addRolloverListener(new RolloverListener() {
    @Override
    public void beforeRollover(RollingFileManager rollingFileManager) {
        // 滚动前逻辑(可选)
    }

    @Override
    public void afterRollover(RollingFileManager rollingFileManager) {
        String rolledFile = rollingFileManager.getPatternProcessor().getCurrentFileName();
        handleRolledFile(rolledFile);
    }
});

三、最终推荐配置

结合官方触发策略和自定义滚动策略,完整XML配置如下:

<Configuration status="warn" name="MyApp">
  <Appenders>
    <RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/app-%d{yyyy-MM-dd-HH-mm}.log">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
      <Policies>
        <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
      </Policies>
      <CustomRolloverStrategy/>
    </RollingFile>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="RollingFile"/>
    </Root>
  </Loggers>
</Configuration>

内容的提问来源于stack exchange,提问作者Programer86

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 15:39:56