org/springframework/boot/logging/logback/defaults.xml的内容和作用

[AI生成]
defaults.xml 是 Spring Boot 日志系统的“最底层基石”

如果说 base.xml 是帮你把日志系统“组装好”的半成品,那么 defaults.xml 就是告诉你“用什么零件、按什么图纸来组装”。它只定义规则、常量和 properties,不生成任何实际的 Appender 或 Root 配置

打开 Spring Boot 的源码包,你会发现 defaults.xml 的真实内容大致如下(为了便于阅读,我加了中文注释,并且按功能分了块):

<configuration>

    <!-- ==================== 1. 默认日志级别定义 ==================== -->
    <!-- 如果 application.yml 没配,就用这里的默认级别 -->
    <property name="CONSOLE_LOG_THRESHOLD" value="${CONSOLE_LOG_THRESHOLD:-TRACE}"/>
    <property name="FILE_LOG_THRESHOLD" value="${FILE_LOG_THRESHOLD:-TRACE}"/>
  
    <!-- 默认的日志文件名,如果你没配,就叫 spring.log -->
    <property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}/spring.log}"/>
  
    <!--滚动文件归档命名格式 -->
    <property name="FILE_LOG_PATTERN" value="${FILE_LOG_PATTERN:-%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
  
    <!-- 控制台日志输出格式 -->
    <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>

    <!-- ==================== 2. 颜色转换规则注册 ==================== -->
    <!-- 引入颜色支持类,使得我们可以用 %clr 关键字来输出彩色日志 -->
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
    <!-- 引入异常格式化支持类 -->
    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />

</configuration>

非常精简!但它包含了极其重要的三个部分,下面逐一拆解:


1. 核心的日志格式模板 (CONSOLE_LOG_PATTERNFILE_LOG_PATTERN)

这是 defaults.xml 最重要的价值。它把控制台格式和文件格式分别定义成了变量字符串,以后所有的 Appender 只需要写 ${CONSOLE_LOG_PATTERN} 就能引用这套无敌复杂的模板。

我们来看看这套在 Spring Boot 启动时,控制台输出的那串带颜色的日志到底是怎么拼出来的。单独把控制台模板拿出来看:

%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} 
%clr(%5p) 
%clr(${PID:- }){magenta} 
%clr(---){faint} 
%clr([%t]){faint} 
%clr(%-40.40logger{39}){cyan} 
%clr(:){faint} 
%m%n%wEx

逐段解析这个“Spring Boot 经典格式”:

  • %clr(...){faint}: clr 是转换符,{faint} 是指定颜色。faint 表示浅灰色。
  • %d{yyyy-MM-dd HH:mm:ss.SSS}: 时间,被包在浅灰色里。
  • %5p: 日志级别(INFO、ERROR等),跟之前讲的 %-5level 类似,右对齐占5个字符。Spring Boot 默认不指定颜色,会根据级别自动变色(如 INFO 绿色,ERROR 红色)。
  • ${PID:- }: 你的 Java 进程号!Spring Boot 特有功能,打印 PID 便于排查问题。用 {magenta} 洋红色标记。
  • ---: 固定的分隔符,浅灰色。
  • [%t]: 线程名,浅灰色。
  • %-40.40logger{39}: 类名。最小宽度 40,最大宽度 40(超过截断,不足右侧补空格),用 {cyan} 青色标记。
  • :: 冒号分隔符,浅灰色。
  • %m: 你的业务日志内容。
  • %n: 换行。
  • %wEx: 异常信息输出,树状化且带空格缩进。

所以,当你看到屏幕上这行字:

2023-10-27 14:30:15.123 INFO 12345 --- [main] c.e.d.MyApplication : Started Application

它实际上是经过了上面这一大串 %clr 包装的结果。

2. application.yml 配置覆盖机制

你可能注意到模板里写满了 ${变量:-默认值} 的语法。这是 Logback 提供的变量替换机制。

意思是:如果你在 application.yml 里配置了这个变量,我就用你配的;没配,我就用冒号后面的默认值。

比如:

  • ${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}:如果你在 application.yml 里配了 logging.pattern.dateformat=yyyy-MM-dd,日志里的时间就没有具体时分秒了。
  • ${CONSOLE_LOG_PATTERN:-xxx}:如果你在 application.yml 里配了 logging.pattern.console=%d{HH:mm:ss} %logger %msg,Spring Boot 就会直接使用你写的简单格式,完全覆盖掉官方默认的彩色长格式。

3. 颜色转换规则 (conversionRule)

这就是上一点提到的 %clr 为什么能起作用的原因。
Logback 本身不认识 %clr 这个转换符。Spring Boot 在这里把它强行注册给了内置的类 ColorConverter

  • conversionWord="clr": 告诉 Logback 遇到 %clr 就去找下面的类处理。
  • converterClass="org.springframework.boot.logging.logback.ColorConverter": 这个类接收到括号里的内容(如 %d{...})输出后,会给这段文本加上 ANSI 颜色控制码(比如 \033[0;35m ... \033[0m),终端就会显示紫红色。

同理,%wEx 被注册给了 ExtendedWhitespaceThrowableProxyConverter。这个类的作用是:当系统抛出 Exception 时,把堆栈信息格式化,处理好缩进和空行,让异常堆栈看起来更整洁。


总结:defaults.xml 做了什么?

它并没有启动日志记录,它只做了两件事:

  1. 声明发明了 %clr%wEx 这两个新词汇(转换器)。
  2. 把用这些新词汇写出来的,长长的一句包含时间、PID、线程、颜色的超级长格式,打包存名为 CONSOLE_LOG_PATTERNFILE_LOG_PATTERN 两个 String 变量。

这就是为什么在我们自己写的 logback-spring.xml 中,如果不引入 defaults.xml,就算你直接复制官方的 %clr 格式字符串,它也毫无颜色且会报错,因为你要么没声明词汇的释义(conversionRule),要么没有那个超级长字符串的现成变量。

posted @ 2026-07-23 17:04  dirgo  阅读(1)  评论(0)    收藏  举报