logback偶现不压缩文件和保存时间配置

问题是新增了错误日志,然后在logback-spring,log中增加了对应的配置,由于说要接入企微机器人,希望能把名称都命名为带日期的,仔细阅读文档发现只要不配置file文件名即可.于是进行了如下配置

 <appender name="ERROR_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--日志文件输出格式 -->
        <encoder>
            <pattern>${FILE_LOG_PATTERN}</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!-- ThresholdFilter过滤低于指定阈值的事件。 对于等于或高于阈值的事件,ThresholdFilter将在调用其decision()方法时响应NEUTRAL。
            但是,将拒绝级别低于阈值的事件 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level><!-- 低于ERROR级别的日志(debug,info)将被拒绝,等于或者高于ERROR的级别将相应NEUTRAL -->
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${LOG_FILE}_error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
            <!--单个日志文件的最大体积-->
            <maxFileSize>${LOG_FILE_MAX_SIZE:-20MB}</maxFileSize>
            <!-- 日志最大的历史 30天 -->
            <maxHistory>${LOG_FILE_MAX_HISTORY:-30}</maxHistory>
        </rollingPolicy>
    </appender>
 <logger name="com.example" level="INFO">
        <appender-ref ref="ERROR_LOG"/>
    </logger>

配置完成后,确实正常的生成了每天的日志文件带日期,但是遇到一个问题,就是当第二天(第三天都可,不是当天就行)没有错误日志写入触发压缩时,这时如果重启服务,启动时不会触发压缩,只会生成新的一个带当天日期的文件,问题就来了,之前的那个文件就一直在那里,不压缩.

为了解决这个问题,看文档,还是没找到,后来debug到服务启动时不会触发压缩,只有新的日志写入才会触发压缩

附上源码中的压缩的方法

ch.qos.logback.core.rolling.RollingFileAppender#rollover

public void rollover() {
        lock.lock();
        try {
            // Note: This method needs to be synchronized because it needs exclusive
            // access while it closes and then re-opens the target file.
            //
            // make sure to close the hereto active log file! Renaming under windows
            // does not work for open files.
            this.closeOutputStream();
            attemptRollover();
            attemptOpenFile();
        } finally {
            lock.unlock();
        }
    }

解决方式就是配置一个file,只能最新的日志暂不加日期了

<file>${LOG_FILE}_error.log</file>

与此同时发现logback-spring.xml不会在jar包启动时spring.config.location指定位置,

可以通过application.yml中的logging.config指定位置

如果不需要读spring的配置也可通过logback.configurationFile配置指定

logback当配置maxHistory为30时究竟是什么时候触发删除之前的日志呢?

分两种情况,第一种是配置cleanHistoryOnStart为true时(该配置默认为false),在服务启动时就会触发删除

第二种情况,就是没有配置,或者配置为false时,和触发滚动压缩一样,也是在有日志写入文件中才会触发,调用ch.qos.logback.core.rolling.TimeBasedRollingPolicy#rollover时

public void rollover() throws RolloverFailure {

        // when rollover is called the elapsed period's file has
        // been already closed. This is a working assumption of this method.

        String elapsedPeriodsFileName = timeBasedFileNamingAndTriggeringPolicy.getElapsedPeriodsFileName();

        String elapsedPeriodStem = FileFilterUtil.afterLastSlash(elapsedPeriodsFileName);

        if (compressionMode == CompressionMode.NONE) {
            if (getParentsRawFileProperty() != null) {
                renameUtil.rename(getParentsRawFileProperty(), elapsedPeriodsFileName);
            } // else { nothing to do if CompressionMode == NONE and parentsRawFileProperty == null }
        } else {
            if (getParentsRawFileProperty() == null) {
                compressionFuture = compressor.asyncCompress(elapsedPeriodsFileName, elapsedPeriodsFileName, elapsedPeriodStem);
            } else {
                compressionFuture = renameRawAndAsyncCompress(elapsedPeriodsFileName, elapsedPeriodStem);
            }
        }
        //此处就是调用清除日志的方法
        if (archiveRemover != null) {
            Date now = new Date(timeBasedFileNamingAndTriggeringPolicy.getCurrentTime());
            this.cleanUpFuture = archiveRemover.cleanAsynchronously(now);
        }
    }
this.cleanUpFuture = archiveRemover.cleanAsynchronously(now);该方法实际上只给线程池中提交了一个任务,真正实现清除的是ch.qos.logback.core.rolling.helper.TimeBasedArchiveRemover#clean方法,如下
    public void clean(Date now) {
 
        long nowInMillis = now.getTime();
        // for a live appender periodsElapsed is expected to be 1
        int periodsElapsed = computeElapsedPeriodsSinceLastClean(nowInMillis);
        lastHeartBeat = nowInMillis;
        if (periodsElapsed > 1) {
            addInfo("Multiple periods, i.e. " + periodsElapsed + " periods, seem to have elapsed. This is expected at application start.");
        }
        for (int i = 0; i < periodsElapsed; i++) {
            int offset = getPeriodOffsetForDeletionTarget() - i;
            Date dateOfPeriodToClean = rc.getEndOfNextNthPeriod(now, offset);
            cleanPeriod(dateOfPeriodToClean);
        }
    }

计算一个周期32天的分钟数46080和14*24=336(14天24小时)取较小的值,然后循环这个对应的次数,去掉-maxHistory - 1加上次数数,然后根据这个偏移量和当前时间获取要清理的日期,用这个日期获取文件,并删除文件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值