如何在登录后关闭应用时滚动日志文件?

问题描述 投票:0回答:1

我有一个每天运行的市场数据Spring Boot应用程序,晚上将关闭它。应用程序关闭后,我要处理记录的市场数据消息。为此,我一直在寻找一种方法,使其能够在关机时(而不是在启动时)翻转日志文件,以便我的后处理应用程序能够以一致的方式读取文件。

当前,我已经创建了一个自定义触发策略,并且使用了以下与市场数据相关的消息的logback配置

@NoAutoStart
public class CustomTriggerPolicy<E> extends SizeAndTimeBasedFNATP<E> {
    @Override
    public boolean isTriggeringEvent(File activeFile, E event) {
        boolean triggeringEvent = super.isTriggeringEvent(activeFile, event);
        if(!triggeringEvent) {
            elapsedPeriodsFileName = getCurrentPeriodsFileNameWithoutCompressionSuffix();
        }
        return triggeringEvent;
    }
}

logback.xml

<configuration>
    <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener"/>
    <shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook">
        <delay>60000</delay>
    </shutdownHook>
    <appender name="MKT-DATA-FIX-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/mkt-data-fix.log</file>
        <append>false</append>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <Pattern>%m%n</Pattern>
        </encoder>

        <!-- rollover daily -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/archived/foo/mkt-data-fix.%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="com.mkt.data.CustomTriggerPolicy">
                <maxFileSize>100GB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>
</configuration>

SpringBootApplication.class(Main class)

@PreDestroy
    public void shutdown() {
        manualLogRollover();
    }

    public void manualLogRollover() {
        try {
            Set<Appender<ILoggingEvent>> loggingAppenders = AppenderUtils.getLoggingAppenders();
            AppenderUtils.rolloverAppenders(loggingAppenders);
        } catch (Exception e) {
            log.warn("Log rollover failed", e);
        }
    }

AppenderUtils.java

public class AppenderUtils {
    public static Set<Appender<ILoggingEvent>> getLoggingAppenders() {
        LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
        Set<Appender<ILoggingEvent>> fileLogAppenders = new HashSet<>();
        for(Logger logger : context.getLoggerList()) {
            for(Iterator<Appender<ILoggingEvent>> index = logger.iteratorForAppenders(); index.hasNext();) {
                Appender<ILoggingEvent> appender = index.next();
                if(appender instanceof RollingFileAppender) {
                    if(appender.getName().equals("MKT-DATA-FIX-LOG") ||
                            appender.getName().equals("MKT-DATA-FIX-EVENT-LOG")) {
                        fileLogAppenders.add(appender);
                    }
                }
            }
        }
        return fileLogAppenders;
    }

    public static void rolloverAppenders(Set<Appender<ILoggingEvent>> appenders) {
        for (Appender<ILoggingEvent> appender : appenders) {
            if (appender instanceof RollingFileAppender) {
                ((RollingFileAppender<ILoggingEvent>) appender).rollover();
            }
        }
    }
}

到目前为止,我已经完成了以下工作;

  1. [在关闭时尝试了手动翻转而没有DelayingShutdownHook,最终导致创建了.tmp文件,并且不能完全完成翻转过程。
  2. 添加一个延迟为1分钟的延迟关机钩子,但似乎logback Compressor的asyncCompress方法返回的Future在30秒后超时,导致出现以下错误
18:16:58,872 |-ERROR in c.q.l.core.rolling.TimeBasedRollingPolicy@398887205 - Timeout while waiting for compression job to finish java.util.concurrent.TimeoutException
        at java.util.concurrent.TimeoutException
        at      at java.util.concurrent.FutureTask.get(FutureTask.java:205)
        at      at ch.qos.logback.core.rolling.TimeBasedRollingPolicy.waitForAsynchronousJobToStop(TimeBasedRollingPolicy.java:137)
        at      at ch.qos.logback.core.rolling.TimeBasedRollingPolicy.stop(TimeBasedRollingPolicy.java:129)
        at      at ch.qos.logback.core.rolling.RollingFileAppender.stop(RollingFileAppender.java:152)
        at      at ch.qos.logback.core.spi.AppenderAttachableImpl.detachAndStopAllAppenders(AppenderAttachableImpl.java:107)
        at      at ch.qos.logback.classic.Logger.detachAndStopAllAppenders(Logger.java:206)
        at      at ch.qos.logback.classic.Logger.recursiveReset(Logger.java:331)iam
        at      at ch.qos.logback.classic.Logger.recursiveReset(Logger.java:338)
        at      at ch.qos.logback.classic.Logger.recursiveReset(Logger.java:338)
        at      at ch.qos.logback.classic.Logger.recursiveReset(Logger.java:338)
        at      at ch.qos.logback.classic.Logger.recursiveReset(Logger.java:338)
        at      at ch.qos.logback.classic.LoggerContext.reset(LoggerContext.java:223)
        at      at ch.qos.logback.classic.LoggerContext.stop(LoggerContext.java:348)
        at      at ch.qos.logback.core.hook.ShutdownHookBase.stop(ShutdownHookBase.java:39)
        at      at ch.qos.logback.core.hook.DelayingShutdownHook.run(DelayingShutdownHook.java:57)
        at      at java.lang.Thread.run(Thread.java:748)

我没有选择权。有谁知道如何实现我在这里寻找的东西?

java logback shutdown appender
1个回答
0
投票

我想我明白了。我必须定义自己的关闭钩子,该钩子会滚动附加程序,然后同步关闭上下文。

我不需要在主类中将滚动作为@PreDestroy的一部分。

public class CustomLogShutdownHook extends ShutdownHookBase {

    @Override
    public void run() {
        addInfo("Rolling over files.");
        try {
            Set<Appender<ILoggingEvent>> loggingAppenders = AppenderUtils.getLoggingAppenders();
            AppenderUtils.rolloverAppenders(loggingAppenders);
        } catch (Exception e) {
            addError("Rollover failed", e);
        }
        addInfo("Shutting down context");
        super.stop();
    }
}

我还移动了我的应用程序以使用FixedWindowRollingPolicy,它可以同步压缩文件,而不是TimeBasedRollingPolicy,它可以异步压缩并导致超时。

logback.xml

<configuration>
    <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener"/>
    <shutdownHook class="com.mkt.data.logback.CustomLogShutdownHook"/>
    <appender name="MKT-DATA-FIX-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/mkt-data-fix.log</file>
        <append>false</append>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <Pattern>%m%n</Pattern>
        </encoder>

        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
            <fileNamePattern>${LOG_HOME}/archived/foo/mkt-data-fix.%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
            <minIndex>0</minIndex>
            <maxIndex>10</maxIndex>
        </rollingPolicy>

        <!-- rollover daily -->
        <triggeringPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/archived/foo/mkt-data-fix.%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="com.mkt.data.CustomTriggerPolicy">
                <maxFileSize>100GB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </triggeringPolicy>
    </appender>
</configuration>
© www.soinside.com 2019 - 2024. All rights reserved.