Spring Boot 3.3.4 升级导致 Logback 之前回滚策略配置不兼容问题解决

前言

在将 Spring Boot 项目升级至 3.3.4 版本后,遇到 Logback 配置的兼容性问题。本文将详细描述该问题的错误信息、原因分析,并提供调整日志回滚策略的解决方案。

错误描述

这是SpringBoot 3.3.3版本之前的回滚策略的配置

xml 复制代码
    <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <fileNamePattern>${LOG_HOME}/%d{yyyy-MM-dd}.%i.log</fileNamePattern>
        <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <maxFileSize>10MB</maxFileSize>
        </timeBasedFileNamingAndTriggeringPolicy>
        <!--日志文档保留天数-->
        <maxHistory>30</maxHistory>
    </rollingPolicy>

当 升级至 Spring Boot 3.3.4 版本后,启动时出现以下报错:

bash 复制代码
Exception in thread "main" java.lang.IllegalStateException: java.lang.IllegalStateException: Logback configuration error detected: 
ERROR in ch.qos.logback.core.model.processor.ImplicitModelHandler - Could not create component [timeBasedFileNamingAndTriggeringPolicy] of type [ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP] java.lang.ClassNotFoundException: ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP
ERROR in c.q.l.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy - Filename pattern [/logs/app/%d{yyyy-MM-dd}.%i.log] contains an integer token converter, i.e. %i, INCOMPATIBLE with this configuration. Remove it.

主要问题出现在 logback 日志配置的 SizeAndTimeBasedFNATP 类以及日志文件命名中的 %i 令牌使用上。

关键错误信息:

  1. java.lang.ClassNotFoundException: ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP
  2. Filename pattern contains an integer token converter, i.e. %i, INCOMPATIBLE with this configuration

原因分析

在升级 Spring Boot 版本至 3.3.4 后,底层的 Logback 版本也随之更新。在较新的 Logback 版本中,以下变化引发了兼容性问题:

  1. SizeAndTimeBasedFNATP 类弃用

    • 在新的 Logback 版本中,SizeAndTimeBasedFNATP 类已经被移除或不再使用。之前用来支持基于大小和时间的日志滚动的策略必须替换为新的策略类。
    • 此类需要被 SizeAndTimeBasedRollingPolicy 替代,它能够同时支持按文件大小和时间进行日志滚动。
  2. 日志文件命名中的 %i 令牌不兼容

    • 日志文件命名模式中使用的 %i 令牌,用于在日志滚动时生成多个文件(如 log.1, log.2 等),但这与 TimeBasedRollingPolicy 不兼容。TimeBasedRollingPolicy 仅基于时间滚动日志,不支持 %i 分片。

解决方案

调整日志回滚策略

为了解决以上问题,我们需要将原有的 TimeBasedRollingPolicy 替换为新的 SizeAndTimeBasedRollingPolicy,并调整日志文件的命名模式以去除不兼容的 %i 令牌。

配置修改

以下是修改后的 logback-spring.xml 配置:

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <!-- SpringBoot默认logback的配置 -->
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>

    <springProperty scope="context" name="APP_NAME" source="spring.application.name"/>
    <property name="LOG_HOME" value="/logs/${APP_NAME}"/>

    <!-- 1. 输出到控制台 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
        <encoder>
            <Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!-- 2. 输出到文件 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/log.log</file>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} -%5level ---[%15.15thread] %-40.40logger{39} : %msg%n%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!-- 使用SizeAndTimeBasedRollingPolicy替代旧的策略 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 滚动后的日志文件命名模式 -->
            <fileNamePattern>${LOG_HOME}/%d{yyyy-MM-dd}-%i.log</fileNamePattern>
            <!-- 日志文件的最大大小 -->
            <maxFileSize>10MB</maxFileSize>
            <!-- 最大保留30天的日志 -->
            <maxHistory>30</maxHistory>
            <!-- 总日志文件大小不超过3GB -->
            <totalSizeCap>3GB</totalSizeCap>
        </rollingPolicy>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
    </appender>

    <!-- 开发环境输出至控制台 -->
    <springProfile name="dev">
        <root level="INFO">
            <appender-ref ref="CONSOLE"/>
        </root>
    </springProfile>

    <!-- 生产环境输出至文件 -->
    <springProfile name="prod">
        <root level="INFO">
            <appender-ref ref="CONSOLE"/>
            <appender-ref ref="FILE"/>
        </root>
    </springProfile>

</configuration>

修改内容说明:

  1. 使用 SizeAndTimeBasedRollingPolicy

    • 该策略同时支持按时间和文件大小滚动日志。与旧的 TimeBasedRollingPolicy 类相比,它是更推荐的滚动策略。
  2. 文件命名模式调整

    • fileNamePattern 中,使用 %d{yyyy-MM-dd}-%i.log 作为文件名格式,这允许日志按照日期命名,并在同一天滚动日志时通过 %i 生成分片文件(如 2024-10-01-1.log, 2024-10-01-2.log 等)。
  3. 限制日志大小和保留时间

    • maxFileSize 设置为 10MB,表示单个日志文件的最大大小。
    • maxHistory 设置为 30,表示最多保留30天的日志文件。
    • totalSizeCap 设置为 3GB,表示日志总大小不能超过 3GB。达到该限制时,将删除最早的日志文件。

总结

在 Spring Boot 升级至 3.3.4 后,由于底层 Logback 版本的更新,原先使用的 TimeBasedRollingPolicy 类和日志文件名中的 %i 令牌会引发兼容性问题。通过调整日志回滚策略,使用新的 SizeAndTimeBasedRollingPolicy 并去除不兼容的文件命名模式,可以顺利解决这些问题,使日志系统恢复正常运行。

相关推荐
TheITSea42 分钟前
云服务器宝塔安装静态网页 WordPress、VuePress流程记录
java·服务器·数据库
AuroraI'ncoding1 小时前
SpringMVC接收请求参数
java
九圣残炎1 小时前
【从零开始的LeetCode-算法】3354. 使数组元素等于零
java·算法·leetcode
天天扭码2 小时前
五天SpringCloud计划——DAY1之mybatis-plus的使用
java·spring cloud·mybatis
程序猿小柒2 小时前
leetcode hot100【LeetCode 4.寻找两个正序数组的中位数】java实现
java·算法·leetcode
不爱学习的YY酱3 小时前
【操作系统不挂科】<CPU调度(13)>选择题(带答案与解析)
java·linux·前端·算法·操作系统
丁总学Java3 小时前
Maven项目打包,com.sun.tools.javac.processing
java·maven
kikyo哎哟喂3 小时前
Java 代理模式详解
java·开发语言·代理模式
duration~3 小时前
SpringAOP模拟实现
java·开发语言
小码ssim3 小时前
IDEA使用tips(LTS✍)
java·ide·intellij-idea