日志框架:Logback

日志框架:Logback

前言

Logback‌ 是一个由 ‌Log4j 创始人 Ceki Gülcü 设计‌的 ‌Java 开源日志框架‌ ,作为 Log4j 的继任者,它以其 ‌高性能、灵活配置‌ 和 ‌原生实现 SLF4J API‌ 等特性,成为 ‌Spring Boot 的默认日志框架‌,并广泛应用于企业级开发

Logback 由三个模块构成,形成清晰的分层架构:

  • ‌logback-core‌:基础模块,提供底层支持,不依赖 SLF4J
  • ‌logback-classic:实现 SLF4J API ,是 log4j 的增强版,‌最常用模块。
  • logback-access:与 Servlet 容器(如 Tomcat )集成,记录 HTTP 访问日志。

其核心三组件为:

  • Logger‌:接收日志请求,决定是否处理(基于日志级别)。
  • Appender‌:定义日志输出目的地,如控制台、文件、数据库。
  • Encoder‌ :负责将日志事件格式化为字符串(替代旧版 Layout),支持二进制输出。

主流日志框架对比

特性 ‌Logback‌ ‌Log4j2‌ ‌java.util.logging (JUL)‌
‌性能‌ 高,异步支持良好 ‌极高‌(Disruptor 异步引擎)
‌SLF4J 集成‌ ‌原生支持‌ 需桥接 不支持
‌配置灵活性‌ 高(XML/Groovy) 极高(XML/JSON/YAML) 低(属性文件)
‌自动重载‌ 支持 支持 不支持
‌社区活跃度‌ 高(稳定维护) 高(活跃更新) 低(JDK 内置,无独立更新)
‌适用场景‌ ‌企业级 Java 项目首选‌,SpringBoot 默认 高并发、极致性能场景 小型工具、无依赖需求

Spring Boot 选择 Logback 作为默认日志,是因为它在兼容性、性能、功能、生态、稳定性、易用性上取得了最佳平衡,完美支撑 "开箱即用" 与生产级需求。

再SpringBoot中使用

Spring Boot 选择 Logback 作为默认日志,提供了两种方式,我们从从简单到复杂、从全局到精细进行讲解。

最简方式:文件配置

特点 :不用写 XML ,纯配置项,适合简单项目。
可配置:日志级别、日志文件、包级别日志、格式等。

  • 全局默认日志级别 :控制所有日志的默认级别,是日志继承的根节点(默认值为 ‌INFO)。根日志记录器是所有日志记录器的父级,当一个日志记录器没有显式设置级别时,它会继承根记录器的级别。
yml 复制代码
logging:
  level:
    root: info

日志级别优先级:TRACE < DEBUG < INFO < WARN < ERROR,仅当请求级别 ≥ Logger 级别时才输出。

假设你将某个 Logger 的级别设置为 INFO,那么INFOWARNERROR 级别的日志会被打印;而 TRACEDEBUG 级别的日志则会被忽略,不会输出。

  • 自定义包 / 类日志级别:设置指定包(或类)的日志记录器级别,用于对特定包或类的输出进行更精细的日志控制,优先级高于根日志记录器。
yml 复制代码
logging:
  level:
    com.baomidou.mybatisplus: DEBUG
  • 直接指定文件名:可以同时指定日志文件的‌路径‌和‌文件名‌。
yml 复制代码
logging:
  file:
    name: ./logs/app.log

项目启动后,如果指定了完整路径(包括文件名),日志将输出到该路径下的指定文件中。若仅指定文件名,则默认在项目根目录下创建该文件。

例如:logging.file.name=/var/log/myapp/app.log 会将日志写入 /var/log/myapp/ 目录下的 app.log 文件中。

  • 只指定目录,自动生成 spring.log:仅用于指定日志文件的‌存储路径‌。
yml 复制代码
logging:
  file:
    path: logs

项目启动后,日志文件的名称默认为 spring.log

例如:logging.file.path=/var/log/myapp 会在 /var/log/myapp/ 目录下生成名为 spring.log 的日志文件。

此外,如果两个属性‌同时配置‌,则 logging.file.name 的优先级更高,会覆盖 logging.file.path 的设置,推荐使用 logging.file.name 以避免混淆并提高可读性。

  • 日志格式:用于定义日志输出格式的属性,自定义日志在控制台或文件中的显示方式。

(1)logging.pattern.console:定义日志输出到控制台的格式。

yml 复制代码
logging:
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%wEx%n"

常用占位符
%d:时间
%thread:线程名
%-5level:级别(左对齐 5 字符宽度,后面自动补空格,全部占满 5 个字符宽度),比如:[INFO ]
%logger{36}:类名(最多 36 字符)
%msg:日志内容
%n:换行
%wEx:异常信息

(2)logging.pattern.file:定义日志输出到文件的格式。

yml 复制代码
logging:
  pattern:
    file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"

(3)logging.pattern.dateformat:统一控制日志时间戳格式。

yml 复制代码
logging:
  # 全局统一时间格式(覆盖默认)
  pattern:
    dateformat: yyyy-MM-dd HH:mm:ss.SSS

logging.pattern.consolelogging.pattern.file都能自定义日期格式,再dateformat中配置统一格式,避免混乱,减少重复代码:

yml 复制代码
logging:
  pattern:
    dateformat: yyyy-MM-dd HH:mm:ss.SSS
    console: "%d [%thread] %-5level %logger{36} - %msg%wEx%n"
    file: "%d [%thread] %-5level %logger{36} - %msg%wEx%n"

(4)logging.pattern.level :定义日志级别(INFOWARNERROR)的显示格式。

常用占位符
%p 输出日志级别(INFO/WARN/ERROR)
%5p 固定占 5 个字符宽度,对齐美观
%clr() Spring 提供的颜色渲染
{bold} 加粗
{red} {yellow} 颜色

yml 复制代码
logging:
  pattern:
    level: "%clr(%5p){faint}%clr(%5p){bold}" # Spring 自带
  • 日志文件滚动切割:用来控制日志文件什么时候切分、保留多久、占用多少空间。

(1)clean-history-on-start :启动时是否清除已归档的历史日志文件。默认 false,一般不用配置,留空即可。

yml 复制代码
logging:
  logback:
    rollingpolicy:
      clean-history-on-start: true

(2)file-name-pattern:当日志文件达到滚动条件(如时间或大小)时,旧日志文件被重命名的格式。它通常包含时间戳和索引占位符,例如:

yml 复制代码
logging:
  logback:
    rollingpolicy:
      file-name-pattern: logs/%d{yyyy-MM}/info.%d{yyyy-MM-dd}.%i.gz

常用占位符
logs/%d{yyyy-MM}:日志存在项目下的 logs 文件夹里,按月创建文件。
%d{yyyy-MM-dd}:按天切割。
%i:同一天内,文件超过大小就递增序号(1、2、3...)。
.log:后缀。
.gz:表示压缩归档文件

(3)max-file-size :单个日志文件最大大小,默认:100MB,超过 100MB 自动切分,生成新文件:

yml 复制代码
logging:
  logback:
    rollingpolicy:
      max-file-size: 500MB

支持单位:KBMBGB

(4)max-history :最多保留最近多少天的日志,默认情况下,max-history 的值通常为 7 天,意味着只保留最近一周的归档日志。‌当 max-history 设置为 0 时,Spring Boot 不会自动删除旧的日志文件

yml 复制代码
logging:
  logback:
    rollingpolicy:
      max-history: 7

(5)total-size-cap:所有日志文件总大小上限,默认不限制。

yml 复制代码
logging:
  logback:
    rollingpolicy:
      total-size-cap: 3GB  # 所有日志文件总大小不超过3GB

完整配置如下:

yml 复制代码
logging:
  logback:
    rollingpolicy:
      file-name-pattern: logs/%d{yyyy-MM}/info.%d{yyyy-MM-dd}.%i.gz
      max-file-size: 500MB
      max-history: 7
      total-size-cap: 3GB

日志存到 logs 目录,按月归类、按日命名,单文件 500MB 拆分、旧日志自动压缩;最多存 7 天 日志,所有日志加起来绝不超过 3GB

  • 编码格式 :默认使用系统默认编码,这可能导致日志文件中出现乱码,特别是当系统默认编码不是 UTF-8 时。

(1)logging.charset.console:设置控制台输出的日志编码格式。

yml 复制代码
logging:
  charset:
    console: UTF-8

(2)logging.charset.file:设置写入文件的日志编码格式。

yml 复制代码
logging:
  charset:
    file: UTF-8
  • 日志分组(批量设置级别):把一堆包归为一组,统一设级别。
yml 复制代码
logging:
  group:
    web: org.springframework.controller,org.springframework.web
    sql: org.mybatis,java.sql
  level:
    web: info
    sql: warn
  • 异常堆栈输出 :默认:%wEx ,会在异常信息的‌开始和结束处添加空行‌。这有助于在日志中更清晰地分隔异常信息,提高可读性。它会输出完整的异常堆栈跟踪,并在前后添加空行。
yml 复制代码
logging:
  exception-conversion-word: "%wEx"
复制代码
10:30:45.123 [main] ERROR com.example.MyClass - 业务处理失败

java.lang.RuntimeException: 业务处理失败
	at com.example.MyClass.main(MyClass.java:10)
Caused by: java.sql.SQLException: 数据库连接失败
	at com.example.MyClass.main(MyClass.java:6)

Process finished with exit code 1

除了%wEx外,还有%ex%rEx%xEx ,这 3 个都是打印异常堆栈的格式:

(1)%ex:这是最基本的异常信息转换符。它会输出异常的类型、消息以及完整的堆栈跟踪信息。这是最常用的异常输出格式。

复制代码
10:30:45.123 [main] ERROR com.example.MyClass - 业务处理失败
java.lang.RuntimeException: 业务处理失败
	at com.example.MyClass.main(MyClass.java:10)
Caused by: java.sql.SQLException: 数据库连接失败
	at com.example.MyClass.main(MyClass.java:6)

(2)%rEx:与 %ex 类似,但会输出异常的‌根原因‌(root cause)信息。它会显示异常的完整堆栈跟踪,但更侧重于异常链的根部原因,这对于理解问题的根本原因很有帮助。

复制代码
10:30:45.123 [main] ERROR com.example.MyClass - 业务处理失败
java.lang.RuntimeException: 业务处理失败
	at com.example.MyClass.main(MyClass.java:10)
Caused by: java.sql.SQLException: 数据库连接失败
	at com.example.MyClass.main(MyClass.java:6)

(3)%xEx:这个转换符不仅输出异常信息,还会在每一行异常信息后面‌追加 JAR 包的信息‌。这对于调试时确定具体是哪个 JAR 包中的类抛出了异常非常有用。它会输出完整的堆栈跟踪,并包含 JAR 包的详细信息。

复制代码
10:30:45.123 [main] ERROR com.example.MyClass - 业务处理失败
java.lang.RuntimeException: 业务处理失败
	at com.example.MyClass.main(MyClass.java:10) [myapp.jar]
Caused by: java.sql.SQLException: 数据库连接失败
	at com.example.MyClass.main(MyClass.java:6) [myapp.jar]
  • 指定日志配置文件 :你不想用默认的 logback-spring.xml,想自己改名字、放别的目录,就必须用 logging.config 指定。

一般情况,默认寻找:src/main/resources/logback-spring.xml文件

如果,你想将文件名改成:my-log.xml 或者放到:resources/config/my-log.xml

yml 复制代码
logging:
  config: classpath:config/my-log.xml
  • 日志写入完整性 :关闭时,保证日志能写完、不丢失,默认:true

程序要立刻退出,但日志可能还在缓冲区里,没来得及写入文件,如果直接退出,最后几条日志就丢了。

yml 复制代码
logging:
  register-shutdown-hook: true  # 开启安全关闭钩子
常用配置

完整且常用的 yml 日志模板:

yml 复制代码
# 日志核心配置
logging:
  # 日志文件路径(自动创建文件夹+文件)
  file:
    name: logs/app.log
  # 日志级别
  level:
    root: info                 # 全局默认级别
    com.example.demo: debug    # 你的包路径(按需改)
  # 日志格式
  pattern:
    # 控制台格式(SpringBoot 官方默认标准格式)
    console: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p){bold} %clr(${PID:- }){magenta} %clr(---){faint} %clr([%5.50t]){faint} %clr(%-40.40logger{39} %line){cyan} %clr(:){faint} %m%n%wEx"
    # 文件格式(和控制台 100% 一模一样,统一整齐)
    file: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %-40logger{39} [%line] - %msg%n"
  # 日志文件滚动切割
  logback:
    rollingpolicy:
      file-name-pattern: logs/%d{yyyy-MM}/info.%d{yyyy-MM-dd}.%i.gz
      max-file-size: 500MB
      max-history: 7
      total-size-cap: 10GB
  # 日志编码格式
  charset:
    console: UTF-8
    file: UTF-8

简单项目、只想改日志级别,推荐用yml方式,快、省事,不需要额外文件;复杂日志规则、多环境、自定义格式,必须用 xml,功能强大、标准。

默认框架配置:XML配置

SpringBoot 加载日志配置的顺序:

logback-spring.xml -> logback.xml -> application.yml / application.properties

yml 配置优先级低于 xml方式,读到 logback.xmllogback-spring.xml后,日志系统已经初始化完成,yml 里的相关配置会失效。

SpringBoot推荐使用logback-spring.xml

logback.xml属于原生 Logback 配置,被 Logback 自己加载,比SpringBoot 容器加载要早,拿不到 SpringBoot 的配置信息;
logback-spring.xmlSpringBoot 接管,SpringBoot 启动后能通过占位符拿到所有配置信息。

logback-spring.xml 默认存放位置(SpringBoot 会自动找的默认文件名):

src/main/resources/logback-spring.xml

如果,你想将文件名改成:my-log.xml 或者 放到:resources/config/my-log.xml(不推荐):

yml 复制代码
logging:
  config: classpath:config/my-log.xml

先在resources目录下创建logback-spring.xml文件,填充Logback基础模板

顶层根标签
  • <configuration>标签:顶层根标签,所有日志配置都必须写在它里面,相当于日志配置的 "总容器"。
xml 复制代码
<!--XML 声明-->
<?xml version="1.0" encoding="UTF-8" ?>
<!--根标签-->
<configuration scan="false" scanPeriod="60 seconds" debug="false">

</configuration>

(1)scan :是否自动扫描配置文件变化,修改 logback.xml 后不用重启项目就能生效。默认值:false

(2)scanPeriod :自动扫描配置文件的间隔时间,只有 scan="true" 时才生效。默认值:60 seconds(1 分钟),单位支持:milliseconds / seconds / minutes / hours

(3)debug :是否打印 logback 自身的内部调试日志。默认值:false

变量 / 属性标签
  • <property>标签 :定义全局变量,方便复用,通过 ${变量名} 引用。
xml 复制代码
<property name="LOG_PATH" value="logs/app" />
<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %-40logger{39} [%line] - %msg%n" />

(1)name:变量名。必填,用于引用的键。

(2)value:变量值。变量的具体内容。

输出器
  • <appender>标签:日志输出目的地:控制台、文件、滚动文件、Socket 等。
xml 复制代码
<!--控制台输出-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
</appender>

(1)name:唯一名称,给 logger 引用。

(2)class :输出器实现类。常用Classch.qos.logback.core.ConsoleAppender(控制台)、ch.qos.logback.core.FileAppender(文件)、ch.qos.logback.core.rolling.RollingFileAppender(滚动文件)、ch.qos.logback.classic.AsyncAppender(异步输出)。

  • ch.qos.logback.core.ConsoleAppender :这是用于将日志输出到控制台的 Appender 。它通常与 <encoder> 配合使用来格式化日志输出。
xml 复制代码
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
</appender>

这个配置会将日志输出到控制台,并按照指定的格式进行格式化。

  • ch.qos.logback.core.FileAppender :将日志输出到文件的 Appender。它会将所有日志写入到指定的文件中。
xml 复制代码
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>logs/app.log</file>
    <append>true</append> <!-- 追加写入 -->
    <charset>UTF-8</charset>
    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %-40logger{39} [%line] - %msg%wEx%n</pattern>
    </encoder>
</appender>

这个配置会一直将日志写入到名为 logs/app.log的文件中,一般不用。

  • ch.qos.logback.core.rolling.RollingFileAppender :这是用于将日志输出到文件,并支持日志滚动(例如按日期或文件大小滚动 )的 Appender 。它通常与 <rollingPolicy><triggeringPolicy> 配合使用。
xml 复制代码
<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>logs/app.log</file>
    <append>true</append>
    <charset>UTF-8</charset>

    <!-- 滚动策略 -->
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <!-- 切割后的文件路径 -->
        <fileNamePattern>logs/%d{yyyy-MM}/app.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
        <!-- 单个文件最大大小 -->
        <maxFileSize>500MB</maxFileSize>
        <!-- 保留30天 -->
        <maxHistory>30</maxHistory>
        <!-- 总大小限制 -->
        <totalSizeCap>3GB</totalSizeCap>
    </rollingPolicy>

    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %-40logger{39} [%line] - %msg%wEx%n</pattern>
    </encoder>
</appender>

特点:按天 / 按大小切割、自动压缩 .gz、自动删除旧日志、控制总占用空间、不占满磁盘。

  • ch.qos.logback.classic.AsyncAppender :用于异步输出日志的 Appender 。它会将日志事件放入一个阻塞队列中,然后由一个或多个后台线程处理这些事件,从而提高日志记录的性能(它自己不写文件,只是包装别的 appender)。
xml 复制代码
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>logs/app.log</file>
    <append>true</append> <!-- 追加写入 -->
    <charset>UTF-8</charset>
    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %-40logger{39} [%line] - %msg%wEx%n</pattern>
    </encoder>
</appender>
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
    <appender-ref ref="FILE"/>
    <queueSize>1024</queueSize>
    <discardingThreshold>0</discardingThreshold>
    <neverBlock>true</neverBlock>
    <includeCallerData>false</includeCallerData>
    <maxFlushTime>1000</maxFlushTime>
</appender>

(1)<appender-ref>标签 :引用一个已定义好的 appender

(2)<queueSize>标签 :异步日志队列大小,最多能缓存 1024 条日志。默认 256

(3)<discardingThreshold>标签 :队列剩余空间低于多少时,开始丢弃低级日志,默认值是 20,你写0表示永远不主动丢弃。

(4)<neverBlock>标签:队列满了,也绝不阻塞业务代码。

(5)<includeCallerData>标签 :是否获取类名、方法名、行号等调用者信息,建议设置false,获取这些信息非常耗性能。

(6)<maxFlushTime>标签:服务关闭时,最多等 1000 毫秒,把队列里剩余日志刷入文件。

日志文件路径
  • <file>标签:设置日志文件路径。
xml 复制代码
<file>${LOG_PATH}/app.log</file>
滚动策略
  • <rollingPolicy>标签:定义日志文件滚动策略,决定何时以及如何滚动日志文件。

常见的滚动策略包括:TimeBasedRollingPolicy (按时间)、SizeAndTimeBasedRollingPolicy (按大小 + 时间)、FixedWindowRollingPolicy(固定窗口滚动,几乎不用)。

TimeBasedRollingPolicy :基于时间进行滚动,例如每天、每小时或每月生成一个新的日志文件app.2026-04-01.logapp.2026-04-02.log

xml 复制代码
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    <fileNamePattern>logs/app.%d{yyyy-MM-dd}.log</fileNamePattern>
    <maxHistory>30</maxHistory>
</rollingPolicy>

(1)<fileNamePattern>标签:指定滚动日志文件的命名模式,通常包含日期或索引等信息。

%d 转换符用于表示日期,可以指定日期格式。

(2)<maxHistory>标签:指定保留多少天。

SizeAndTimeBasedRollingPolicy:既按天切分,单个文件超过指定大小也会立即切分。

xml 复制代码
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
    <fileNamePattern>${LOG_PATH}/app.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
    <maxFileSize>100MB</maxFileSize>
    <maxHistory>30</maxHistory>
    <totalSizeCap>10GB</totalSizeCap>
</rollingPolicy>

%i 转换符用于表示文件索引(当按大小滚动时)。

(1)<maxFileSize>标签:指定单个日志文件的最大大小。

(2)<totalSizeCap>标签 :指定所有历史日志文件的总大小上限。当总大小超过此值时,将删除最旧的日志文件,默认值为 0(表示无总大小限制)。

FixedWindowRollingPolicy :基于文件数量进行滚动,通过文件索引(如 %i)来管理归档文件(几乎不用)。

xml 复制代码
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
    <fileNamePattern>logs/app.%i.log.gz</fileNamePattern>
    <minIndex>1</minIndex>
    <maxIndex>3</maxIndex>
</rollingPolicy>

(1)<minIndex>标签:指定滚动文件的最小索引值。

(2)<maxIndex>标签:指定滚动文件的最大索引值。

在实际应用中,SizeAndTimeBasedRollingPolicy 更为常用,因为它更符合现代日志管理的需求。

日志格式编码
  • <encoder>标签:用于对日志事件进行格式化,将日志信息转换为可输出的字符串格式。
xml 复制代码
<encoder>
	<!--日志格式-->
    <pattern>${LOG_PATTERN}</pattern>
    <!--编码格式-->
    <charset>UTF-8</charset>
</encoder>
日志过滤器
  • <filter>标签:过滤器日志事件,只输出符合条件的日志。
xml 复制代码
<filter class="ch.qos.logback.classic.filter.LevelFilter">
    <level>ERROR</level>
    <onMatch>ACCEPT</onMatch>
    <onMismatch>DENY</onMismatch>
    <evaluator>
        <expression>message.contains("login")</expression>
    </evaluator>
</filter>
  • <onMatch>标签 :配置符合过滤条件时的操作,值‌:ACCEPT (放行)、NEUTRAL (不处理)、DENY(拒绝)。
  • <onMismatch>标签 :配置不符合过滤条件时的操作,值‌:ACCEPT (放行)、NEUTRAL (不处理)、DENY(拒绝)。

最常用过滤器:

(1)ThresholdFilter :阈值过滤器,只输出指定级别的日志(>=Level)。

xml 复制代码
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
    <level>INFO</level>
</filter>

(2) LevelFilter:精确级别过滤器,只输出 / 只拒绝 某一个精确级别的日志。

xml 复制代码
<!--只输出 ERROR-->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
    <level>ERROR</level>         <!-- 精确匹配 -->
    <onMatch>ACCEPT</onMatch>    <!-- 匹配就放行 -->
    <onMismatch>DENY</onMismatch><!-- 不匹配就拒绝 -->
</filter>

(3)EvaluatorFilter:自定义表达式 / 条件过滤器。

xml 复制代码
<!--包含 login 才输出-->
<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
    <evaluator>
        <expression>message.contains("login")</expression>
    </evaluator>
    <onMatch>ACCEPT</onMatch>
    <onMismatch>DENY</onMismatch>
</filter>
其它不常用标签
  • <append>标签 :控制日志是否追加到文件末尾,而不是覆盖文件内容。 默认:true,表示追加日志。
xml 复制代码
<append>true</append>
  • <target>标签 :指定日志输出到System.outSystem.err,通常用于 ConsoleAppender (控制台输出)。默认值为 System.out
xml 复制代码
<target>System.err</target>
  • <prudent>标签 :控制日志文件的写入方式,确保在多线程或多进程环境中安全地写入日志,默认值:false
xml 复制代码
<prudent>true</prudent>

开启后性能下降 5--10 倍。

  • <triggeringPolicy>标签:定义‌何时‌触发日志滚动,即什么条件满足时会触发滚动操作。

滚动策略有:TimeBasedRollingPolicy (时间触发)到时间就切、SizeBasedTriggeringPolicy(大小触发)文件超过指定大小就切。

xml 复制代码
<!-- 旧式写法(现在基本不用) -->
<rollingPolicy class="FixedWindowRollingPolicy">
    <fileNamePattern>logs/app.%i.log</fileNamePattern>
</rollingPolicy>

<!-- 旧式必须写这个 -->
<triggeringPolicy class="SizeBasedTriggeringPolicy">
    <maxFileSize>100MB</maxFileSize>
</triggeringPolicy>

在新版 Logback 中,<triggeringPolicy> 已经不需要手动写了!TimeBasedRollingPolicy 内部自带时间触发和SizeAndTimeBasedRollingPolicy 内部自带大小 + 时间触发。

常用清单

<appender>标签比较详细且常用的配置示例:

xml 复制代码
<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <!-- 文件路径 -->
    <file>logs/server.log</file>
    <!-- 追加写入 -->
    <append>true</append>

	<!-- 滚动策略 -->
	<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
	   <fileNamePattern>${LOG_PATH}/app.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
	   <maxFileSize>100MB</maxFileSize>
	   <maxHistory>30</maxHistory>
	   <totalSizeCap>10GB</totalSizeCap>
	</rollingPolicy>

    <!-- 过滤器:只输出 INFO 及以上 -->
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>INFO</level>
    </filter>
    
    <!-- 日志格式 -->
    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        <charset>UTF-8</charset>
    </encoder>
</appender>

除了上述介绍的,还有很多,有兴趣的可以自行研究。

日志器标签
  • <logger>标签 :定义特定包或类的日志行为。它允许你为不同的包或类设置不同的日志级别,从而实现对日志输出的精细化控制。
xml 复制代码
<logger name="包名/类全名" level="日志级别" additivity="true/false">
    <appender-ref ref="输出到哪里" />
</logger>
  • name :必填,要控制的包名或类全名,例如,name="com.example.myapp"
  • level :可选属性,用于设置日志级别,输出什么级别以上的日志。默认继承父 <logger> 的日志级别。可选值包括 TRACE < DEBUG < INFO < WARN < ERROR
  • additivity :可选属性,控制日志是否向上传播到父级 Logger 。默认值为 true
xml 复制代码
<!-- 让 controller 包输出 DEBUG 日志,其他包保持 INFO -->
<logger name="com.example.controller" level="DEBUG" />
<!-- 打印 MyBatis SQL -->
<logger name="com.example.mapper" level="DEBUG" />

引用一个已定义好的 appender

xml 复制代码
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
</appender>
<!-- 为特定包设置日志级别和 Appender -->
<logger name="com.example.myapp" level="INFO">
    <appender-ref ref="STDOUT" />
</logger>
根日志器
  • <root>标签 :默认全局日志配置,所有 logger 最终都会走到这里。整个应用所有日志的最终接收者、最终输出者,整个配置文件只能出现一个 <root>标签

如果你没有给某个包配置 <logger>,所有类的日志级别默认使用 root 的级别。

xml 复制代码
<root level="INFO">

你配置的控制台、文件输出,最终都要在 root 里绑定才会生效。

xml 复制代码
<root level="INFO">
    <appender-ref ref="CONSOLE" />
    <appender-ref ref="FILE" />
</root>

<logger>标签是局部配置,<root>标签是全局兜底。

<logger name="xxx">只对 name 指定的包 / 类生效;<root>对整个项目所有类生效,是全局默认规则。

所以如果你这样配:

xml 复制代码
<logger name="com.example" level="DEBUG">
    <appender-ref ref="FILE"/>
</logger>

<root level="INFO">
    <appender-ref ref="CONSOLE"/>
</root>

那么 com.example 包的日志:会输出到 FILE (自己 logger ),同时也会输出到 CONSOLE (传给 root)。

如果不想向上传递:

xml 复制代码
<logger name="com.example" level="DEBUG"  additivity="false">
    <appender-ref ref="FILE"/>
</logger>

这样就不会再CONSOLE输出。

上下文标签
  • <contextName>标签 :设置日志上下文名称,用于区分不同应用的日志,可通过 %contextName 在日志格式中输出。
xml 复制代码
    <!-- 设置上下文名称 -->
<contextName>spring-boot-app</contextName>
	<!-- 控制台输出 appender -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg (%contextName)%n</pattern>
    </encoder>
</appender>

如果只是配置了 <contextName> 而没有在 <pattern> 中使用 %contextName,那么该名称不会出现在日志输出中。

读取Spring配置

<springProperty> 标签主要用于在 Logback 配置文件中引用 Spring 应用程序的属性值。它允许你在 Logback 的配置中使用 Spring 环境中的属性,从而实现日志配置与应用程序配置的一致性。

xml 复制代码
<springProperty scope="context" name="property_name" source="property_source" [defaultValue="default_value"] />
  • scope:指定从 Spring 上下文中读取属性值,通常设置为 context
  • name:在 Logback 配置中定义的属性名称。
  • source:指定从 Spring 应用程序配置文件中读取的属性源。
  • defaultValue:可选属性,如果 Spring 上下文中找不到指定的属性,则使用默认值。

假设你的 Spring Boot 应用程序的 application.properties 文件中包含如下配置:

perl 复制代码
spring.application.name=my-app
server.port=8080
logging.path=/var/logs/myapp

Logback 的配置文件 logback-spring.xml 中,你可以使用 <springProperty> 标签来动态引用这些属性值:

xml 复制代码
<configuration scan="false" debug="false">
    <!-- 从 Spring 上下文中读取属性值 -->
    <springProperty scope="context" name="spring_application_name" source="spring.application.name"/>
    <springProperty scope="context" name="server_port" source="server.port"/>
    <springProperty scope="context" name="LOG_HOME" source="logging.path" defaultValue="../logs"/>

    <!-- 定义日志输出格式 -->
    <property name="CONSOLE_LOG_PATTERN" value="%clr(${spring_application_name}){cyan}||%clr(%d{ISO8601}){faint}|%clr(%p)|%X{requestId}|%X{X-B3-TraceId:-}|%X{requestIp}|%X{userIp}|%ip|${server_port}|${PID}|%clr(%t){faint}|%clr(%.40logger{39}){cyan}.%clr(%method){cyan}:%L|%m|%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>

    <!-- 定义控制台输出 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
        </encoder>
    </appender>
</configuration>

除此之外,还可以使用<springProperty> 标签进行多环境切换,示例如下:

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

    <!-- 读取 SpringBoot yml 中的服务名(可选) -->
    <springProperty scope="context" name="APP_NAME" source="spring.application.name" defaultValue="app"/>

    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %-40logger{39} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>logs/${APP_NAME}.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>logs/%d{yyyy-MM}/%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
            <maxFileSize>500MB</maxFileSize>
            <maxHistory>30</maxHistory>
            <totalSizeCap>3GB</totalSizeCap>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %-40logger{39} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender">
    </appender>

    <!-- 开发环境 dev -->
    <springProfile name="dev">
        <root level="DEBUG">
            <appender-ref ref="CONSOLE"/>
        </root>
    </springProfile>

    <!-- 测试环境、生产环境共用 -->
    <springProfile name="test,prod">
        <root level="INFO">
            <appender-ref ref="CONSOLE"/>
            <appender-ref ref="FILE"/>
        </root>
    </springProfile>

</configuration>

大多数情况下,用一套配置就行。

MDC

LogbackMDCMapped Diagnostic Context ,映射诊断上下文)是 SLF4J 提供的一种方便在多线程条件下记录日志的功能。它本质上是一个与当前线程绑定的哈希表,可以往其中添加键值对。

在分布式系统或多线程场景中,一个请求可能会经过多个线程、多个服务处理。MDC 可以统一标记同一请求的所有日志,通过在 MDC 中设置全局唯一的 traceId,让该请求触发的所有日志都携带这个 ID

代码里放入值:

java 复制代码
import org.slf4j.MDC;

// 在请求入口处设置
MDC.put("traceId", UUID.randomUUID().toString());
MDC.put("userId", userId);

xml 中通过%X{traceId}%X{userId}追加:

xml 复制代码
<configuration>
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d [%thread] %-5level %-40logger{39} [%line] [traceId=%X{traceId}] [userId=%X{userId}] - %msg%n</pattern>
        </encoder>
    </appender>
</configuration>

请求结束后清除:

java 复制代码
MDC.clear();

输出效果:

bash 复制代码
2026-04-05 22:50:00.123 [http-nio-8080-exec-1] INFO  com.example.controller [25] [traceId=a1b2c3d4] [userId=10086] - 查询订单成功

MDC 为在复杂的分布式系统中追踪日志提供了有效的解决方案,使得日志能够携带上下文信息,便于问题排查和系统监控。

注解使用

@Slf4jLombok 提供的一个注解,用于在 Java 类中快速集成日志功能。

传统方式定义 Logger

java 复制代码
public class UserService {
    private static final Logger log = LoggerFactory.getLogger(UserService.class);
    
    public void login(String username) {
        log.info("用户 {} 登录成功", username);
    }
}

使用 @Slf4j 注解方式:

java 复制代码
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class UserService {
    public void login(String username) {
        log.info("用户 {} 登录成功", username);
    }
}

编译后,class 文件里自动变成:

java 复制代码
public class UserController {
    private static final Logger log = LoggerFactory.getLogger(UserController.class);
}

使用 @Slf4j 需要:添加 Lombok 依赖、在 IDE 中安装 Lombok 插件:

xml 复制代码
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <scope>provided</scope>
</dependency>

@Slf4j 就是帮你偷懒的,少写一行代码。

常用配置

完整且常用的 xml 日志模板:

xml 复制代码
<?xml version="1.0" encoding="UTF-8" ?>
<configuration scan="false" debug="false">
    <!-- 1. 引入Spring默认配置(解决clr) -->
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    <property name="LOG_PATH" value="logs/app"/>
    <property name="LOG_PATTERN"
              value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p){bold} %clr(${PID:- }){magenta} %clr(---){faint} %clr([%5.50t]){faint} %clr(%-40.40logger{39} %line){cyan} %clr(:){faint} %m%n"/>
    <property name="FILE_LOG_PATTERN"
              value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %-40logger{39}:%line - %msg%n"/>
    <property name="ENCODING" value="UTF-8"/>

    <!-- 控制台输出 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${LOG_PATTERN}</pattern>
            <charset>${ENCODING}</charset>
        </encoder>
    </appender>

    <!-- 滚动文件输出 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_PATH}/info.log</file>
        <encoder>
            <pattern>${FILE_LOG_PATTERN}</pattern>
            <charset>${ENCODING}</charset>
        </encoder>

        <!-- 滚动策略 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/%d{yyyy-MM}/info.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <maxFileSize>500MB</maxFileSize>
            <maxHistory>30</maxHistory>
            <totalSizeCap>10GB</totalSizeCap>
        </rollingPolicy>
    </appender>

    <!-- 错误日志文件输出 -->
    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_PATH}/error.log</file>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/%d{yyyy-MM}/error.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <maxFileSize>500MB</maxFileSize>
            <maxHistory>30</maxHistory>
            <totalSizeCap>10GB</totalSizeCap>
        </rollingPolicy>
        <encoder>
            <pattern>${FILE_LOG_PATTERN}</pattern>
            <charset>${ENCODING}</charset>
        </encoder>
    </appender>

    <!-- 包级别日志控制 -->
    <logger name="org.springframework" level="WARN"/>
    <logger name="com.baomidou.mybatisplus" level="WARN"/>
    <logger name="com.yourpackage" level="INFO"/>

    <!-- 根日志(全局生效) -->
    <root level="INFO">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="FILE"/>
        <appender-ref ref="ERROR_FILE"/>
    </root>
</configuration>
相关推荐
回到原点的码农1 天前
Spring Boot 3.3.4 升级导致 Logback 之前回滚策略配置不兼容问题解决
java·spring boot·logback
Flittly1 天前
【SpringAIAlibaba新手村系列】(11)Embedding 向量化与向量数据库
java·笔记·spring·ai·springboot
九皇叔叔2 天前
005-SpringSecurity-Demo 配置外部文件映射
java·springboot·文件·springsecurity
玛卡巴卡ldf3 天前
【Springboot5】审批流工作流引擎(业务、审批分离)排除if else
java·springboot
shark22222223 天前
springboot中配置logback-spring.xml
spring boot·spring·logback
一生了无挂3 天前
springboot使用logback自定义日志
java·spring boot·logback
九皇叔叔3 天前
001-SpringSecurity-Demo 创建项目
java·springboot·springsecurity
pupudawang4 天前
使用 Logback 的最佳实践:`logback.xml` 与 `logback-spring.xml` 的区别与用法
xml·spring·logback