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

文章讲述了如何在Logback配置中处理错误日志,使用带有日期的文件名,以及解决重启服务后旧日志未压缩的问题。还讨论了logback-spring.xml的配置路径和日志文件历史管理机制。

问题是新增了错误日志,然后在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加上次数数,然后根据这个偏移量和当前时间获取要清理的日期,用这个日期获取文件,并删除文件

<think>好的,用户问的是如何在logback-spring中配置日志永久保存。首先,我需要确定logback-spring是Spring Boot中使用的日志框架,通常使用logback-spring.xml或application.properties进行配置。 用户想要永久保存日志,可能意味着需要避免日志文件被覆盖或删除。通常日志文件会有滚动策略,比如按时间或大小滚动,但默认可能只保留一段时间的文件。要永久保存,可能需要调整滚动策略中的历史保留策略。 在logback中,常用的Appender是RollingFileAppender或者TimeBasedRollingPolicy。需要设置maxHistory参数,这个参数控制保留的归档文件的最大周期数。如果要永久保存,可能需要将maxHistory设为一个非常大的值,或者设置,但根据文档,如果设置的话可能默认保留7天? 另外,可能需要配置totalSizeCap,防止磁盘空间被占满,但用户的需求是永久保存,所以可能需要忽略这个设置,或者让用户自行注意磁盘空间。 接下来,需要给出具体的配置示例。比如在logback-spring.xml中配置RollingFileAppender,使用TimeBasedRollingPolicy,设置fileNamePattern,并将maxHistory设为足够大的数值,比如9999,这样相当于永久保留。 同时,可能需要提到Spring Boot的application.properties中的logging.file配置,指定日志文件的路径名称,确保日志输出到正确的文件。 还要考虑同环境下的配置,比如开发环境生产环境可能需要同的设置,但用户的问题主要是永久保存,所以重点在配置参数。 可能还需要提醒用户注意磁盘空间的问题,永久保存可能导致磁盘空间耗尽,建议定期清理或监控。 最后,相关问题应该包括如何按大小滚动日志、如何压缩旧日志、如何删除旧日志文件,以及如何配置日志级别,这些都是日志配置相关的常见问题。</think>在logback-spring中配置日志永久保存的核心步骤如下: 1. **配置文件位置** 在`src/main/resources`下创建`logback-spring.xml`文件 2. **核心配置示例** ```xml <configuration> <!-- 定义日志输出路径 --> <property name="LOG_PATH" value="logs"/> <!-- 控制台日志输出 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> </encoder> </appender> <!-- 文件日志输出(永久保存) --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_PATH}/app.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 按天滚动 --> <fileNamePattern>${LOG_PATH}/app.%d{yyyy-MM-dd}.log</fileNamePattern> <!-- 设置极大值实永久保存 --> <maxHistory>9999</maxHistory> <!-- 可选:设置总保留大小(如1GB) --> <!-- <totalSizeCap>1GB</totalSizeCap> --> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> </encoder> </appender> <!-- 绑定日志级别 --> <root level="info"> <appender-ref ref="STDOUT"/> <appender-ref ref="FILE"/> </root> </configuration> ``` 3. **Spring Boot配置补充** 在`application.properties`中添加: ```properties # 指定日志文件名称 logging.file=logs/app.log # 禁用默认的日志清理策略 logging.cleaner.level=OFF ``` **注意事项**: - 磁盘空间监控:建议配合监控系统防止磁盘占满 - 文件压缩:可通过添加`<zip>`扩展名实自动压缩(如`app.%d{yyyy-MM}.zip`) - 多环境配置:可在logback-spring.xml中使用`<springProfile>`区分环境
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值