SpringBoot项目logback-spring.xml日志管理配置

一、为什么需要专门配置 logback-spring.xml?

1、与默认配置的区别

  • Spring Boot 默认日志配置:Spring Boot 内置了 Logback 的默认配置,开箱即用;
  • logback-spring.xml 的优势:专门为 Spring Boot 设计的配置文件,支持 Spring 特有的功能扩展;
  • 命名约定:使用 logback-spring.xml而非 logback.xml可以让 Spring Boot 完全控制日志初始化过程。

2、解决的核心问题

  • 实现多环境(dev/test/prod)差异化的日志配置;
  • 支持 Spring Profile 条件化配置;
  • 在日志配置中使用 Spring 属性占位符。

二、配置 logback-spring.xml 的主要优点?

1、Spring Profile 支持(最重要优势)

<!-- 开发环境:控制台输出,级别为DEBUG -->
<springProfile name="dev">
    <root level="DEBUG">
        <appender-ref ref="CONSOLE"/>
    </root>
</springProfile>

<!-- 生产环境:文件输出,级别为INFO -->
<springProfile name="prod">
    <root level="INFO">
        <appender-ref ref="FILE"/>
        <appender-ref ref="ERROR_FILE"/>
    </root>
</springProfile>

2、多环境适配

  • 不同环境使用不同的日志策略
  • 开发环境:侧重可读性,控制台彩色输出;
  • 生产环境:侧重性能和分析,文件输出+日志切割;
  • 测试环境:可配置为收集特定包/类的详细日志。

3、性能优化

<!-- 异步日志提升性能 -->
<appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender">
    <appender-ref ref="FILE"/>
    <queueSize>512</queueSize>
    <discardingThreshold>0</discardingThreshold>
</appender>

4、精细化日志控制

<!-- 针对不同包设置不同日志级别 -->
<logger name="com.example.service" level="DEBUG"/>
<logger name="org.hibernate" level="WARN"/>
<logger name="org.apache.kafka" level="INFO"/>

5、Spring 属性注入

<!-- 使用Spring属性 -->
<property resource="application.properties"/>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>${LOG_PATH:-./logs}/application.log</file>
    ...
</appender>

6、结构化日志管理

  • 按级别分离日志(INFO/ERROR分开存储),方便快速排查、定位错误信息;

  • 按时间/大小滚动分割归档、自动压缩(可节省60~80磁盘空间);

  • 自动清理历史日志文件。

<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <fileNamePattern>logs/application.%d{yyyy-MM-dd}.log.gz</fileNamePattern>
        <maxHistory>30</maxHistory> <!-- 保留30天 -->
    </rollingPolicy>
</appender>

7、增强的可读性

  • 支持彩色控制台输出;

  • 自定义日志格式模板;

  • 包含有用的上下文信息(traceId、用户ID等)。

8、监控与诊断优化

  • 集成 MDC(Mapped Diagnostic Context)用于链路追踪;

  • 支持 JSON 格式输出,便于日志采集分析;

  • 可配置敏感信息脱敏。

三、使用注意事项

1、文件存放位置

  • 通常放在 src/main/resources/目录下

2、加载顺序

  • Spring Boot 会优先加载 logback-spring.xml

3、热加载

  • 配置 scan="true"支持修改后自动重载(生产环境建议关闭)

4、向后兼容

  • 也支持标准的 logback.xml,但会失去 Spring 集成特性

四、生产配置推荐示例(可直接复制使用,局部需按需调整)

<?xml version="1.0" encoding="UTF-8"?>
<!--scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。(生产建议关闭,基本不会在生产上改动)-->
<!--scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟(生产建议长一些,避免太频繁的性能消耗)。-->
<!--debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。-->
<configuration scan="false" scanPeriod="5 minutes" debug="false">

    <!-- 定义日志文件的存储地址和文件名称,简单说就是定义变量,后面可以使用${xx}来使用变量 -->
    <!--info日志文件存储层级-->
    <property name="INFO_LOG_FILE_LEVEL" value="logs/info"/>
    <!--error日志文件存储层级-->
    <property name="ERROR_LOG_FILE_LEVEL" value="logs/error"/>
    <!--info日志文件名称-->
    <property name="INFO_LOG_FILE_NAME" value="info"/>
    <!--error日志文件名称-->
    <property name="ERROR_LOG_FILE_NAME" value="error"/>

    <!-- appender是configuration的子节点,是负责写日志的组件 -->
    <!-- ConsoleAppender:把日志输出到控制台 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 默认情况下,每个日志事件都会立即刷新到基础输出流。这种默认方法更安全,因为如果应用程序在没有正确关闭appender的情况下退出,则日志事件不会丢失 -->
        <!-- 但为了显着增加日志记录吞吐量,可以将immediateFlush属性设置为false -->
        <immediateFlush>true</immediateFlush>
        <encoder>
            <!--[TRACEID:%X{traceId}]:用于日志线程跟踪,结合MDC(映射诊断上下文)工具-->
            <!-- %37():如果字符没有37个字符长度,则左侧用空格补齐 -->
            <!-- %-37():如果字符没有37个字符长度,则右侧用空格补齐 -->
            <!-- %15.15():如果记录的线程字符长度小于15(第一个)则用空格在左侧补齐,如果字符长度大于15(第二个),则从开头开始截断多余的字符 -->
            <!-- %msg:日志打印详情 -->
            <!--%cyan():颜色转换词,用于在控制台中区分不同的日志部分-->
            <!--:%line:前面的:为分隔符,%line表示会输出日志代码所在的行号-->
            <!-- %-40.40():-表示左对齐(默认是右对齐)如果记录的logger字符长度小于40(第一个)则用空格在右侧补齐,如果字符长度大于40(第二个),则从开头开始截断多余的字符 -->
            <!-- %n:换行符 -->
            <!-- %highlight():转换说明符以粗体红色显示其级别为ERROR的事件,红色为WARN,BLUE为INFO,以及其他级别的默认颜色 -->
            <pattern>[TRACEID:%X{traceId}] %d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level)-[%15.15(%thread)] %cyan(%-40.40(%logger{40}):%line): %msg%n</pattern>
            <!-- 控制台也要使用UTF-8,不要使用GBK,否则会中文乱码 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!-- info 日志收集-->
    <!-- RollingFileAppender:滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件,
        以下的大概意思是:
                1.先按日期存日志,日期变了,将前一天的日志文件名重命名为XXX%日期%索引,新的日志仍然是${INFO_LOG_FILE_NAME}.log
                2.如果日期没有发生变化,但是当前日志的文件大小超过100MB时,对当前日志进行分割、重命名、压缩
     -->
    <appender name="INFO_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--日志文件路径和名称-->
        <File>${INFO_LOG_FILE_LEVEL}/${INFO_LOG_FILE_NAME}.log</File>
        <!--是否追加到文件末尾,默认为true-->
        <append>true</append>
        <!--日志级别收集匹配规则-->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <!-- 如果命中ERROR就禁止这条日志 -->
            <onMatch>DENY</onMatch>
            <!-- 如果没有命中就接收 -->
            <onMismatch>ACCEPT</onMismatch>
        </filter>
        <!--有两个与RollingFileAppender: 交互的重要子组件:
                    RollingPolicy:    负责执行翻转所需的操作。
                    TriggeringPolicy: 将确定是否以及何时发生翻转。因此RollingPolicy负责什么和TriggeringPolicy负责什么时候
            RollingFileAppender必须同时设置RollingPolicy和TriggeringPolicy;但如果其RollingPolicy也实现了TriggeringPolicy接口,则只需要显式指定前者-->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 日志文件的名字会根据fileNamePattern的值,每隔一段时间改变一次 -->
            <!-- 文件名:${INFO_LOG_FILE_LEVEL}/${INFO_LOG_FILE_NAME}-2024-02-01-0.log.gz -->
            <!-- 注意:SizeAndTimeBasedRollingPolicy中 %i和%d令牌都是强制性的,必须存在要不会报错 -->
            <fileNamePattern>${INFO_LOG_FILE_LEVEL}/${INFO_LOG_FILE_NAME}-%d{yyyy-MM-dd}-%i.log.gz</fileNamePattern>
            <!-- 每产生一个日志文件,该日志文件的保存期限为180天, maxHistory的单位是根据fileNamePattern中的翻转策略自动推算出来的.
                例如上面选用了yyyy-MM-dd,则单位为天
                如果上面选用了yyyy-MM,则单位为月,另外上面的单位默认为yyyy-MM-dd-->
            <maxHistory>180</maxHistory>
            <!-- 每个日志文件到10mb的时候开始切分,最多保留180天,但最大到20GB,哪怕没到180天也要删除多余的日志 -->
            <totalSizeCap>20GB</totalSizeCap>
            <!-- 应用启动时立即清理过期日志文件 -->
            <cleanHistoryOnStart>true</cleanHistoryOnStart>
            <!-- maxFileSize:文件分片大小,100MB,不宜太小,避免频繁分片消耗 -->
            <maxFileSize>100MB</maxFileSize>
        </rollingPolicy>
        <!--编码器-->
        <encoder>
            <!--指定日志输出格式-->
            <pattern>[TRACEID:%X{traceId}] %d{yyyy-MM-dd HH:mm:ss.SSS} %-5level-[%15.15(%thread)] %-40.40(%logger{40}:%line): %msg%n</pattern>
            <!--设置字符集,防止中文乱码-->
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!-- 异步INFO日志收集器:包装INFO_LOG,实现异步写入,提升性能 -->
    <appender name="ASYNC_INFO" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 队列大小,默认256,设置为512以应对突发流量 -->
        <queueSize>512</queueSize>
        <!-- 丢弃阈值,0表示不丢弃,队列满时阻塞 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 是否永不阻塞,false表示队列满时阻塞业务线程,确保日志不丢失 -->
        <neverBlock>false</neverBlock>
        <!-- 包装实际的INFO_LOG appender -->
        <appender-ref ref="INFO_LOG"/>
    </appender>

    <!-- error 日志收集-->
    <appender name="ERROR_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--日志文件路径和名称-->
        <File>${ERROR_LOG_FILE_LEVEL}/${ERROR_LOG_FILE_NAME}.log</File>
        <!--是否追加到文件末尾,默认为true-->
        <append>true</append>
        <!-- ThresholdFilter过滤低于指定阈值的事件。对于等于或高于阈值的事件,ThresholdFilter将在调用其decision方法时响应NEUTRAL。但将拒绝级别低于阈值的事件 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <!-- 低于ERROR级别的日志(debug,info)将被拒绝,等于或者高于ERROR的级别将接收 -->
            <level>ERROR</level>
        </filter>
        <!--有两个与RollingFileAppender交互的重要子组件:
                    RollingPolicy:    负责执行翻转所需的操作。
                    TriggeringPolicy: 将确定是否以及何时发生翻转。因此RollingPolicy负责什么和TriggeringPolicy负责什么时候
            RollingFileAppender必须同时设置RollingPolicy和TriggeringPolicy;但如果其RollingPolicy也实现了TriggeringPolicy接口,则只需要显式指定前者-->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 日志文件的名字会根据fileNamePattern的值,每隔一段时间改变一次 -->
            <!-- 文件名:${ERROR_LOG_FILE_LEVEL}/${ERROR_LOG_FILE_NAME}.2024-02-01.0.log.gz -->
            <!-- 注意:SizeAndTimeBasedRollingPolicy中 %i和%d令牌都是强制性的,必须存在要不会报错 -->
            <fileNamePattern>${ERROR_LOG_FILE_LEVEL}/${ERROR_LOG_FILE_NAME}.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
            <!-- 每产生一个日志文件,该日志文件的保存期限为180天, maxHistory的单位是根据fileNamePattern中的翻转策略自动推算出来的.
                例如上面选用了yyyy-MM-dd,则单位为天
                如果上面选用了yyyy-MM,则单位为月,另外上面的单位默认为yyyy-MM-dd-->
            <maxHistory>180</maxHistory>
            <!-- 每个日志文件到10mb的时候开始切分,最多保留180天,但最大到20GB,哪怕没到180天也要删除多余的日志 -->
            <totalSizeCap>20GB</totalSizeCap>
            <!-- 应用启动时立即清理过期日志文件 -->
            <cleanHistoryOnStart>true</cleanHistoryOnStart>
            <!-- maxFileSize:文件分片大小,100MB,不宜太小,避免频繁分片消耗 -->
            <maxFileSize>100MB</maxFileSize>
        </rollingPolicy>
        <!--编码器-->
        <encoder>
            <!--指定日志输出格式-->
            <pattern>[TRACEID:%X{traceId}] %d{yyyy-MM-dd HH:mm:ss.SSS} %-5level-[%15.15(%thread)] %-40.40(%logger{40}:%line): %msg%n</pattern>
            <!--设置字符集,防止中文乱码-->
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!--  (root)根记录器  -->
    <!-- 开发环境:控制台输出,级别为DEBUG -->
    <springProfile name="dev">
        <root level="DEBUG">
            <!--控制台输出-->
            <appender-ref ref="CONSOLE"/>
            <!--INFO 日志同步写入-->
            <appender-ref ref="INFO_LOG"/>
            <!--ERROR 日志同步写入-->
            <appender-ref ref="ERROR_LOG"/>
        </root>
        <!-- 开发环境:启用MyBatis SQL日志,便于调试 -->
        <!-- 自己项目的包路径 -->
        <logger name="com.cloud.mapper" level="DEBUG"/>
    </springProfile>

    <!-- 生产环境:文件输出,级别为INFO -->
    <springProfile name="prod">
        <root level="INFO">
            <!--控制台输出-->
            <appender-ref ref="CONSOLE"/>
            <!--按需选择:INFO 日志同步写入,日志完整度要求较高、低流量应用等场景使用-->
            <appender-ref ref="INFO_LOG"/>
            <!--按需选择:INFO 日志异步写入(若需提升日志性能并允许日志存在记录延迟跟丢失风险,则可采用。虽然队列满时会阻塞确保不丢失,但应用可能不正常关闭导致日志丢失)-->
<!--            <appender-ref ref="ASYNC_INFO"/>-->
            <!--ERROR 日志同步写入(确保关键错误日志不丢失)-->
            <appender-ref ref="ERROR_LOG"/>
        </root>
        
        <!-- 生产环境:如需临时启用MyBatis SQL日志排查问题,取消下面注释并重启应用 -->
        <!-- 自己项目的包路径 -->
        <!--    <logger name="com.cloud.mapper" level="TRACE"/> -->
    </springProfile>

    <!-- 其他框架日志配置(按需启用) -->
<!--    <logger name="org.springframework" level="DEBUG"/>  -->  <!-- Spring框架DEBUG日志 -->
<!--    <logger name="org.mybatis" level="DEBUG"/>  -->  <!-- MyBatis框架DEBUG日志 -->
<!--    <logger name="io.lettuce.*" level="INFO"/>  -->  <!-- Redis客户端 -->
<!--    <logger name="io.netty.*" level="ERROR"/>  -->  <!-- Netty网络通信 -->
<!--    <logger name="com.rabbitmq.*" level="DEBUG"/>  -->  <!-- RabbitMQ -->
</configuration>
posted @ 2026-01-20 16:26  flycloudy  阅读(37)  评论(0)    收藏  举报