LogBack是 Spring Boot 项目(Spring Boot 默认使用 Logback 作为日志框架)。Logback 提供了更简洁的配置、更快的执行速度、更小的内存占用,并支持多种日志输出方式和灵活的配置选项。
日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出
在 Spring Boot 项目中,Logback 是默认的日志框架 ,它被广泛用于日志的采集、格式化、输出和管理。Spring Boot 对 Logback 提供了良好的集成支持,开发者可以通过简单的配置实现日志的集中管理、异步写入、按需过滤等功能。
Boot中Logback的默认行为
默认日志框架
- Spring Boot 默认使用 Logback 作为日志实现框架。
- 无需额外添加依赖(
spring-boot-starter已默认包含logback-classic)。 - 支持通过
application.properties或application.yml动态配置日志级别。
默认日志输出
- 控制台输出 :默认将日志输出到控制台(使用
ConsoleAppender)。 - 日志级别 :默认日志级别为
INFO。 - 日志格式 :默认使用 Spring Boot 提供的美化格式
Boot中Logback的配置方式
application.yml
logging:
level:
root: INFO
com.example.service: DEBUG
org.springframework.web: WARN
file:
name: logs/app.log
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
- 优点:简单易用,适合快速配置。
- 缺点:无法实现复杂的日志行为(如异步日志、多 Appender、Filter 等)。
yml和xml的优先级
在 Spring Boot 项目中:
- 存在
logback-spring.xml:优先使用logback-spring.xml的日志配置,application.yml的logging配置被忽略。 - 不存在
logback-spring.xml:使用application.yml中的logging配置。
logback自定义配置

根节点<configuration>
- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true
- scanPeriod:设置监测配置文件是否有修改的时间间隔
- debug:true打印出logback内部日志信息,实时查看logback运行状态。默认值false
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="false" scanPeriod="60 seconds" debug="false">
</configuration>
子节点<appender>
Appender 是负责将日志事件输出到指定目的地的核心组件。每个 Appender 定义了一个日志输出的目标(如控制台、文件、数据库等),并通过 Layout/Encoder 和 Filter 控制日志的格式和过滤逻辑。
每个 Appender 包含以下关键元素:
- 目标 :日志输出的位置(如控制台、文件、网络等)。
- Layout/Encoder :定义日志的格式(如文本、JSON、XML)。
- Filter :控制哪些日志事件需要被处理或忽略。

常见 Appender
ConsoleAppender:输出到控制台。FileAppender:输出到文件。RollingFileAppender:支持滚动策略(如按时间或大小滚动日志文件)。SocketAppender:通过网络发送日志到远程服务器。SMTPAppender:通过邮件发送日志。AsyncAppender:异步日志输出,减少对主线程的影响。
ConsoleAppender
将日志输出到控制台,适用于开发调试或实时监控
<property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${log.pattern}</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
FileAppender
将日志写入指定文件,需要持久化日志但无需滚动的场景
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>logs/app.log</file>
<append>true</append> <!-- 是否追加写入 -->
<encoder>
<pattern>%d{HH:mm:ss} [%thread] %-5level %logger - %msg%n</pattern>
</encoder>
</appender>
RollingFileAppender(常用)
将日志写入指定文件,需要持久化日志且需要日志文件滚动的场景(按大小或时间归档)
核心组件
- RollingPolicy :定义滚动策略(如
TimeBasedRollingPolicy或SizeAndTimeBasedRollingPolicy)。 - TriggeringPolicy :触发滚动的条件(如文件大小)。
TimeBasedRollingPolicy
时间维度
<appender name="ROLLING" class="ch.qos.logback.core.RollingFileAppender">
<file>logs/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天滚动一次,保留30天历史日志 -->
<fileNamePattern>logs/app.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss} [%thread] %-5level %logger - %msg%n</pattern>
</encoder>
<!-- 此日志文件只记录warn级别的,上级别和下级别都不会记录 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
SizeAndTimeBasedRollingPolicy
结合了时间和大小的双重维度
- 每次写入日志时,检查当前文件大小是否超过
maxFileSize。 - 如果超过,则触发滚动,生成新的文件(
%i序号递增)。 - 示例 :logs/app.%d{yyyy-MM-dd}.%i.log
生成文件名:
app.2023-10-01.0.log(第一个文件)app.2023-10-01.1.log(因大小超限生成的第二个文件)app.2023-10-02.0.log(第二天的新文件)
<appender name="ROLLING" class="ch.qos.logback.core.RollingFileAppender">
<!-- 当前写入的日志文件 -->
<file>logs/app.log</file>
<!-- 定义滚动策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 文件名模式:按天滚动,且文件大小不超过 100MB -->
<fileNamePattern>logs/app.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 单个文件最大大小,默认 10MB -->
<maxFileSize>100MB</maxFileSize>
<!-- 日志文件最大保留天数 -->
<maxHistory>30</maxHistory>
<!-- 总日志大小限制(可选) -->
<totalSizeCap>1GB</totalSizeCap>
</rollingPolicy>
<!-- 日志格式 -->
<encoder>
<pattern>%d{HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
SMTPAppender
通过邮件发送日志(如 ERROR 级别日志)
<appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
<smtpHost>smtp.example.com</smtpHost>
<to>admin@example.com</to>
<from>logger@example.com</from>
<subject>ERROR: %logger{20} - %m</subject>
<evaluator class="ch.qos.logback.classic.boolex.OnErrorEvaluator"/>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%d{HH:mm:ss} [%thread] %-5level %logger - %msg%n</pattern>
</layout>
</appender>
DBAppender
将日志写入预定义的数据库表
<appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
<connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
<driverClass>com.mysql.cj.jdbc.Driver</driverClass>
<url>jdbc:mysql://localhost:3306/logs</url>
<user>root</user>
<password>password</password>
</connectionSource>
</appender>
AsyncAppender
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="ROLLING_FILE" />
<queueSize>1024</queueSize> <!-- 队列大小 -->
<discardingThreshold>0</discardingThreshold> <!-- 丢弃阈值 -->
</appender>
异步机制:
- 使用
BlockingQueue缓冲日志事件 - 工作线程从队列取事件交给目标 Appender
关键参数:
queueSize:队列容量(默认256)discardingThreshold:队列剩余容量阈值,低于此值丢弃 WARN 以下日志includeCallerData:是否收集调用者数据(影响性能)
缺点
- 如果服务崩溃,容易造成日志丢失
Appender的Filter
Filter 的作用
- 日志筛选 :根据日志级别、内容、上下文等条件,决定是否输出该日志。
- 条件过滤 :支持基于正则表达式、自定义规则等复杂条件筛选。
- 多级过滤 :可以在一个 Appender 中配置多个 Filter,按顺序执行过滤逻辑。
Filter 的执行流程
-
Filter 是在 Appender 内部配置的。
-
日志事件进入 Appender 后,会依次经过每个 Filter。
-
Filter 返回以下三种状态之一:
FilterReply.ACCEPT:接受该日志,继续处理。FilterReply.DENY:拒绝该日志,直接丢弃。FilterReply.NEUTRAL:不处理,继续下一个 Filter。
常见的 Filter 类型及配置示例
LevelFilter
根据日志级别进行过滤,只允许指定级别的日志通过。
示例:只输出 ERROR 级别的日志
<appender name="ERROR_ONLY" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
onMatch:匹配时的行为(ACCEPT表示接受)。onMismatch:不匹配时的行为(DENY表示拒绝)。
ThresholdFilter
根据日志级别阈值 进行过滤,允许等于或高于指定级别的日志通过。
示例:只输出 WARN 及以上级别的日志
<appender name="WARN_THRESHOLD" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
</filter>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
- 特点 :比
LevelFilter更灵活,适用于需要过滤多个级别的情况。
EvaluatorFilter
基于 正则表达式 或 自定义条件表达式 进行日志过滤。
示例:匹配包含 “error” 关键字的日志
<appender name="KEYWORD_FILTER" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
<evaluator>
<expression>message.contains("error")</expression>
</evaluator>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
expression:支持 Java 表达式(如message.contains("error"))。- 可用于过滤特定异常、用户ID、请求参数等。
Filter 的组合使用(Filter Chain)
可以在一个 Appender 中配置多个 Filter,形成过滤链 ,按顺序执行过滤逻辑。
<appender name="CHAIN_FILTER" class="ch.qos.logback.core.ConsoleAppender">
<!-- 第一个 Filter:只允许 WARN 及以上级别通过 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
</filter>
<!-- 第二个 Filter:只允许包含 "error" 的日志通过 -->
<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
<evaluator>
<expression>message.contains("error")</expression>
</evaluator>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
自定义 Filter
public class CustomFilter extends Filter<ILoggingEvent> {
@Override
public FilterReply decide(ILoggingEvent event) {
if (event.getMessage().contains("important")) {
return FilterReply.ACCEPT;
} else {
return FilterReply.DENY;
}
}
}
<appender name="CUSTOM_FILTER" class="ch.qos.logback.core.ConsoleAppender">
<filter class="com.example.CustomFilter" />
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
子节点<logger>
可选节点
<logger> 用于定义特定包或类的日志记录行为
-
指定日志输出的包或类 :通过
name属性指定日志记录器的名称(通常是 Java 包名或类名)。 -
控制日志级别(TRACE, DEBUG, INFO, WARN, ERROR)
-
关联 Appender(决定日志输出位置)
-
控制日志事件传递(叠加性)
<logger name="cn.xxx" level="WARN" additivity="false">
<appender-ref ref="BIZ_LOG_FILE" />
</logger>
| name | 必填,指定日志记录器的名称(通常是包名或类名)。 |
|---|---|
| level | 可选,设置该日志记录器的日志级别。如果不设置,则继承父级root日志级别。 |
| additivity | 可选,默认为true,表示是否将日志传递给父级记录器(如 root)。设为false表示不继承父级日志行为。 |
适用场景
- 避免日志重复输出 :当某个
<logger>已绑定特定 Appender,不希望其日志再被全局 Appender 捕获时,设置additivity="false"。 - 模块化日志管理 :为不同模块(如 service、dao、controller)配置独立的日志输出路径和级别。
动态控制日志级别
在 Spring Boot 中,可以通过 application.properties 动态设置日志级别,但xml配置优先
logging.level.com.example.service=DEBUG
logging.level.com.example.dao=INFO
注意事项
- 若同时出现对同一个包的logger定义,取最后一个
<logger name="cn.xxx" level="info" />
<!-- 只取WARN -->
<logger name="cn.xxx" level="WARN" />
- 若出现子包和父包,则会出现子包覆盖父包部分,但子包外部分仍沿用父包配置
<logger name="cn.xxx" level="info" />
<!-- 仅覆盖api包下的配置 -->
<logger name="cn.xxx.user.api" level="WARN" />
- 如果需要同时设置多个属性 (如级别和输出目标),应合并到同一个
<logger>中
<!-- 业务日志(WARN) -->
<appender name="BIZ_LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 其他配置... -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 应用日志(ERROR) -->
<appender name="APP_LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 其他配置... -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
</appender>
<!-- 控制台日志(INFO) -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- 其他配置... -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 统一 Logger 配置 -->
<logger name="zsoft.gov" level="INFO" additivity="false">
<appender-ref ref="BIZ_LOG_FILE" />
<appender-ref ref="APP_LOG_FILE" />
<appender-ref ref="STDOUT" />
</logger>
子节点<root>
root代表 根日志记录器(Root Logger) ,是整个日志系统的默认配置中心 。所有其他 <logger> 节点如果没有显式指定日志级别或 Appender,都会继承 <root> 的配置。
<root level="info">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
<appender-ref ref="INFO_FILE"/>
</root>
logback自定义样例
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds">
<!-- 定义日志路径(可从外部配置文件注入) -->
<property name="LOG_HOME" value="/opt/logs/myapp" />
<property name="APP_NAME" value="myapp" />
<!-- 日志格式模板 -->
<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}.%M\(%line\) - %msg%n"/>
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- 业务日志文件输出(INFO 级别) -->
<appender name="BIZ_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/${APP_NAME}-biz.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/${APP_NAME}-biz-%d{yyyy-MM-dd}-%i.log.gz</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
<!-- 仅输出 INFO 级别 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 错误日志文件输出(ERROR 级别) -->
<appender name="ERROR_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/${APP_NAME}-error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/${APP_NAME}-error-%d{yyyy-MM-dd}-%i.log.gz</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
<!-- 仅输出 ERROR 级别 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
</appender>
<!-- SQL 日志文件输出(DEBUG 级别) -->
<appender name="SQL_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/${APP_NAME}-sql.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/${APP_NAME}-sql-%d{yyyy-MM-dd}.log.gz</fileNamePattern>
<maxHistory>7</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %msg%n</pattern>
</encoder>
<!-- 仅输出 DEBUG 级别 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 异步日志(提升性能) -->
<appender name="ASYNC_BIZ" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="BIZ_LOG" />
<queueSize>1024</queueSize>
<discardingThreshold>0</discardingThreshold>
</appender>
<appender name="ASYNC_ERROR" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="ERROR_LOG" />
</appender>
<!-- Root Logger -->
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="ASYNC_BIZ" />
<appender-ref ref="ASYNC_ERROR" />
</root>
<!-- 第三方组件日志级别控制 -->
<logger name="org.springframework" level="WARN" />
<logger name="org.hibernate" level="WARN" />
<logger name="org.apache.zookeeper" level="ERROR" />
<logger name="org.apache.kafka" level="WARN" />
<!-- 指定包的日志级别 -->
<logger name="com.example.myapp.service" level="DEBUG" />
<logger name="com.example.myapp.repository" level="DEBUG" />
<!-- SQL 日志绑定到特定包 -->
<logger name="com.example.myapp.repository" level="DEBUG" additivity="false">
<appender-ref ref="SQL_LOG" />
</logger>
</configuration>
Spring Boot项目中Logback的解析与应用
1443

被折叠的 条评论
为什么被折叠?



