Spring Boot 集成 Logback 日志框架:控制台与文件日志、按日期和大小拆分的实战配置
【免费下载链接】spring-boot-demo🚀一个用来深入学习并实战 Spring Boot 的项目。项目地址: https://gitcode.com/gh_mirrors/sp/spring-boot-demo
本篇文章基于 spring-boot-demo 项目中的 demo-logback 模块,系统讲解如何在 Spring Boot 应用中集成 Logback 日志框架:从 Maven 依赖、Lombok
@Slf4j注解的使用,到logback-spring.xml中 ConsoleAppender、RollingFileAppender、LevelFilter、ThresholdFilter 以及"日期 + 大小"双重滚动策略的完整配置。读完本文,你将掌握一套可直接复用的生产级 Logback 配置方案,实现控制台日志与文件日志并存、INFO 与 ERROR 日志分离归档、日志按天按大小自动拆分的完整能力。
模块概览:demo-logback 在项目中的定位
demo-logback 是 spring-boot-demo 聚合工程(根目录 pom.xml 中以<module>demo-logback</module>声明)下的一个独立子模块,其目的是演示 Spring Boot 集成 Logback 后如何记录程序运行日志。整个模块结构十分精简:
demo-logback/ ├── pom.xml # Maven 构建配置 ├── src/main/java/com/xkcoding/logback/ │ └── SpringBootDemoLogbackApplication.java # 启动类(含日志演示代码) ├── src/main/resources/ │ ├── application.yml # 应用配置(端口 / 上下文路径) │ └── logback-spring.xml # Logback 核心配置 └── src/test/java/com/xkcoding/logback/ └── SpringBootDemoLogbackApplicationTests.java # 上下文加载测试该模块演示的核心能力可概括为三点:
- 同时输出控制台日志和文件日志;
- 文件日志按日期(天)和大小(MB)双重维度拆分归档;
- INFO 与 ERROR 两类日志分文件记录,互不污染。
一、pom.xml:最小化依赖组合
模块的 pom.xml 继承了父工程com.xkcoding:spring-boot-demo:1.0.0-SNAPSHOT(父工程版本管理见根目录 pom.xml,其中spring.boot.version为2.1.0.RELEASE、java.version为1.8),自身只声明了三个依赖:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies>要点说明:
- 不需要显式引入 Logback 依赖。Spring Boot 的
spring-boot-starter-logging已默认集成 Logback,且被spring-boot-starter-web传递引入,开箱即用。 spring-boot-starter-web为本模块提供 Web 容器能力,同时带来默认日志依赖;lombok提供@Slf4j注解,自动生成log静态字段,简化日志对象获取;spring-boot-starter-test(scope 为 test)用于支撑 SpringBootDemoLogbackApplicationTests.java 中的上下文加载测试。
二、启动类:五种日志级别与异常堆栈的输出演示
SpringBootDemoLogbackApplication.java 是整个演示的核心代码,它用@Slf4j注入log对象,在应用启动后依次输出 TRACE、DEBUG、INFO、WARN、ERROR 五个级别的日志,并主动触发一次除零异常来演示异常堆栈的记录:
@SpringBootApplication @Slf4j public class SpringBootDemoLogbackApplication { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(SpringBootDemoLogbackApplication.class, args); int length = context.getBeanDefinitionNames().length; log.trace("Spring boot启动初始化了 {} 个 Bean", length); log.debug("Spring boot启动初始化了 {} 个 Bean", length); log.info("Spring boot启动初始化了 {} 个 Bean", length); log.warn("Spring boot启动初始化了 {} 个 Bean", length); log.error("Spring boot启动初始化了 {} 个 Bean", length); try { int i = 0; int j = 1 / i; } catch (Exception e) { log.error("【SpringBootDemoLogbackApplication】启动异常:", e); } } }这段代码包含两个值得注意的工程实践:
- 占位符
{}传参:日志消息使用{}占位符并传入length变量,相比字符串拼接,可避免在日志级别不满足输出条件时产生无谓的字符串创建开销; - 异常堆栈输出:
log.error("...", e)将异常对象作为最后一个参数传入,Logback 会自动打印完整堆栈。这里通过1 / 0触发ArithmeticException,用于验证 ERROR 日志文件能够完整记录异常信息。
日志级别之间存在大小关系:TRACE < DEBUG < INFO < WARN < ERROR。在 root 级别配置为info的前提下,TRACE 和 DEBUG 日志会被过滤掉,最终只有 INFO、WARN、ERROR 三条正常日志和一条异常 ERROR 日志会进入输出——这一现象可以直接用来说明"根级别决定全局日志下限"的机制。
三、logback-spring.xml:生产级日志配置逐段拆解
模块的完整配置文件位于 demo-logback/src/main/resources/logback-spring.xml。关于文件命名,需要特别说明:
- 使用
logback-spring.xml而非logback.xml,是 Spring Boot 官方推荐做法。logback-spring.xml支持 Spring 扩展标签(如<springProfile>)并且不会被 Logback 原生加载器提前接管,从而可以借助springProfile实现按环境(dev/test/prod)差异化配置; - 该文件若放置于
src/main/resources下,Spring Boot 会自动发现并作为日志配置生效。
3.1 引入 Spring Boot 默认日志基线
<configuration> <property name="FILE_ERROR_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} %file:%line: %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/> <include resource="org/springframework/boot/logging/logback/defaults.xml"/><include resource="org/springframework/boot/logging/logback/defaults.xml"/>引入 Spring Boot 自带的基础配置,其中定义了CONSOLE_LOG_PATTERN、FILE_LOG_PATTERN等默认输出模板变量,保证与 Spring Boot 默认日志风格一致;- 开头通过
<property>自定义了FILE_ERROR_PATTERN,用于 ERROR 日志文件。它复用了FILE_LOG_PATTERN的默认结构,并追加了%file:%line(输出日志产生的源文件与行号),且各环节都提供了:-形式的默认值兜底,即使外部没有定义环境变量也能正常渲染。
3.2 控制台日志 Appender:LevelFilter 只保留 INFO
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>INFO</level> </filter> <encoder> <pattern>${CONSOLE_LOG_PATTERN}</pattern> <charset>UTF-8</charset> </encoder> </appender>ConsoleAppender负责向标准输出(控制台)写日志;LevelFilter是精确匹配过滤器:<level>INFO</level>表示仅当日志级别恰好等于INFO 时才放行(LevelFilter 默认onMatch=ACCEPT、onMismatch=DENY);- 输出格式使用 Spring Boot 默认的
CONSOLE_LOG_PATTERN,编码为 UTF-8,避免中文乱码。
3.3 INFO 文件 Appender:LevelFilter 精确过滤掉 ERROR
<appender name="FILE_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender"> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>DENY</onMatch> <onMismatch>ACCEPT</onMismatch> </filter> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <FileNamePattern>logs/demo-logback/info.created_on_%d{yyyy-MM-dd}.part_%i.log</FileNamePattern> <maxHistory>90</maxHistory> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>2MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <encoder> <pattern>${FILE_LOG_PATTERN}</pattern> <charset>UTF-8</charset> </encoder> </appender>这段配置在原文档中有一句非常关键的经验注释:"如果只是想要 Info 级别的日志,只是过滤 info 还是会输出 Error 日志,因为 Error 的级别高"。也就是说,不能简单地用"等于 INFO"的过滤来圈定 INFO 文件的范围——因为文件 Appender 收到的日志不受输出级别"等于"约束,更高等级的 ERROR 也会流向这里。因此这里采用了反向策略:
LevelFilter匹配ERROR级别;onMatch=DENY:一旦匹配到 ERROR 级别就拒绝;onMismatch=ACCEPT:其他级别(INFO、WARN 等)放行。
这样 FILE_INFO 文件就能稳定地只保留 INFO 及其以下(含 DEBUG 等按需放行)的非 ERROR 日志,而 ERROR 被单独导走。
同时,<File>标签被注释掉(<!--<File>logs/info.demo-logback.log</File>-->),只保留<FileNamePattern>。原文档也给出了对应的解释:
- 如果同时配置
<File>与<FileNamePattern>,则当天的日志先写入<File>指定的文件,次日滚动时再按<FileNamePattern>改名归档(即<File>中始终是当天日志); - 如果只配置
<FileNamePattern>(本模块的做法),则所有日志直接按文件名模板生成,不带固定活动文件。
3.4 ERROR 文件 Appender:ThresholdFilter 只保留 ERROR 及以上
<appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>Error</level> </filter> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <FileNamePattern>logs/demo-logback/error.created_on_%d{yyyy-MM-dd}.part_%i.log</FileNamePattern> <maxHistory>90</maxHistory> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>2MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <encoder> <pattern>${FILE_ERROR_PATTERN}</pattern> <charset>UTF-8</charset> </encoder> </appender>与 INFO 文件形成对比的是,ERROR 文件使用ThresholdFilter——它是阈值过滤:<level>Error</level>表示只放行级别大于等于 ERROR的日志(即 ERROR 及其以上)。这正是原文档注释中所说的"如果只是想要 Error 级别的日志,那么需要过滤一下,默认是 info 级别的"的含义:文件 Appender 默认接收的是当前 logger 传入的所有日志,若不设 ThresholdFilter,INFO/WARN 会混入其中。
值得留意的是,ERROR 文件的 pattern 使用了自定义的FILE_ERROR_PATTERN,它相比 INFO 文件多输出%file:%line,便于问题定位。
3.5 按日期 + 大小双重拆分的滚动策略
INFO 与 ERROR 两个文件 Appender 的滚动策略一致,都是"时间 + 大小"双重滚动:
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <FileNamePattern>logs/demo-logback/info.created_on_%d{yyyy-MM-dd}.part_%i.log</FileNamePattern> <maxHistory>90</maxHistory> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>2MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy>各配置项含义与取值如下:
| 配置项 | 当前值 | 作用 |
|---|---|---|
rollingPolicy(TimeBasedRollingPolicy) | 按时间滚动 | 以%d{yyyy-MM-dd}为维度,每天一个日志归档周期 |
FileNamePattern | logs/demo-logback/info.created_on_%d{yyyy-MM-dd}.part_%i.log | 定义归档文件命名规则;%d为日期,%i为同一日期内因大小触发拆分的序号 |
maxHistory | 90 | 只保留最近 90 天的日志,过期日志自动清理,防止磁盘被日志填满 |
totalSizeCap | 注释状态(示例给出1GB) | 日志总容量上限,超过则删除最旧日志;按需启用 |
timeBasedFileNamingAndTriggeringPolicy(SizeAndTimeBasedFNATP) | 时间 + 大小复合触发 | 在按天滚动的基础上叠加按大小滚动 |
maxFileSize | 2MB | 单个活动日志文件的大小上限(原文档注释说明 Logback 默认值为 10MB,此处设置为 2MB 便于演示滚动效果);达到该值后生成新的.part_%i.log文件 |
此外,配置中还以注释形式保留了另一种纯大小触发策略SizeBasedTriggeringPolicy(<maxFileSize>1KB</maxFileSize>),供读者对比"纯大小滚动"与"时间+大小滚动"的差异:前者不关心日期、文件到达阈值即滚动,后者则同时受日期周期与文件大小双重约束。
3.6 root 日志级别与 Appender 挂载
<root level="info"> <appender-ref ref="CONSOLE"/> <appender-ref ref="FILE_INFO"/> <appender-ref ref="FILE_ERROR"/> </root>root是日志树的最顶层 logger,level="info"意味着全局只有 INFO 及以上级别的日志会被处理,这也解释了启动类中 TRACE、DEBUG 两条日志不会输出的原因;- 三个 Appender 依次挂载:所有日志先经 CONSOLE 精确过滤、再进 FILE_INFO(拒 ERROR)、最后进 FILE_ERROR(收 ERROR 及以上),从而形成"控制台 + 普通文件 + 错误文件"三层输出体系。
3.7 输出格式说明
INFO 文件与控制台使用 Spring Boot 默认 pattern(由defaults.xml提供),ERROR 文件使用自定义FILE_ERROR_PATTERN。原文档示例中的自定义 pattern 为:
%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n各转换符含义:
| 转换符 | 含义 |
|---|---|
%date | 日志产生时间,默认格式yyyy-MM-dd HH:mm:ss.SSS |
%thread | 输出日志的线程名 |
%-5level | 日志级别,左对齐占 5 位(如INFO、ERROR) |
%logger{50} | logger 名称,最长截断为 50 个字符 |
%file | 日志输出所在的源文件名 |
%line | 日志输出所在的源码行号 |
%msg | 日志消息内容 |
%n | 换行符 |
配置文件中通过${...}引用 Spring Boot 预置模板(CONSOLE_LOG_PATTERN、FILE_LOG_PATTERN)或自定义属性(FILE_ERROR_PATTERN),既保持了默认观感,又能灵活追加%file:%line这类定位信息。
四、application.yml:与日志无关的基础配置
demo-logback/src/main/resources/application.yml 中只配置了应用端口与上下文路径,与日志功能无直接关系:
server: port: 8080 servlet: context-path: /demo说明该模块启动后,Web 服务监听 8080 端口、访问前缀为/demo。日志输出位置由logback-spring.xml中的FileNamePattern决定(即运行目录下的logs/demo-logback/文件夹),与server配置相互独立。
五、运行与验证
5.1 启动应用
在仓库根目录或 demo-logback 模块目录下执行 Maven 命令即可启动:
# 在模块目录下启动 mvn spring-boot:run # 或先打包再运行 mvn clean package -DskipTests java -jar target/demo-logback.jar启动成功后,控制台会看到 CONSOLE Appender 输出的 INFO 日志;target外的运行目录下会生成logs/demo-logback/目录,内含:
logs/demo-logback/ ├── info.created_on_2026-09-18.part_0.log # 普通日志(按天 + 2MB 拆分) └── error.created_on_2026-09-18.part_0.log # 错误日志(含异常堆栈)由于maxFileSize设为 2MB,日志量较大时同一日期会出现.part_0、.part_1……依次递增的多个分片;超过maxHistory=90天的旧日志会被自动清理。
5.2 上下文加载测试
模块自带的测试类 SpringBootDemoLogbackApplicationTests.java 通过@SpringBootTest加载完整应用上下文:
@RunWith(SpringRunner.class) @SpringBootTest public class SpringBootDemoLogbackApplicationTests { @Test public void contextLoads() { } }该测试用于验证配置与 Bean 装配的正确性,可执行mvn test运行。测试通过即代表日志配置(logback-spring.xml)被正确加载、应用上下文可正常启动。
5.3 观察要点
启动后可以直观验证以下几点:
- 控制台输出 INFO 格式日志,且因
LevelFilter精确匹配只显示 INFO 级别; info.*.log中不会出现 ERROR 日志(已被onMatch=DENY拦截);error.*.log中完整保留 ERROR 日志及ArithmeticException的完整堆栈;- TRACE、DEBUG 日志因 root 级别为
info而不产生输出,若想观察它们,可将<root level="info">临时改为debug或trace再启动。
六、延伸:从 demo-logback 到项目级日志体系
在 spring-boot-demo 聚合工程中,日志能力不止于此。项目根 README.md 中列出集成的日志相关模块包括logback(日志)与aopLog(通过 AOP 记录 Web 请求日志,位于 demo-log-aop)。这意味着在本项目里,Logback 负责"日志怎么写",而 AOP 日志负责"记录哪些内容",二者配合可构建完整的请求日志链路。
对于生产实践,基于本模块的配置可以直接扩展的方向包括:
- 使用
<springProfile name="dev|prod">按环境切换输出级别与文件路径(这是选用logback-spring.xml命名的主要收益); - 将
totalSizeCap从注释状态启用,为日志目录设置总容量上限; - 按业务模块拆分 logger,为不同包路径配置独立 Appender 与级别;
- 接入日志采集组件(如 Graylog,参见项目中的 demo-graylog),将文件日志进一步汇聚到集中日志平台。
小结
本模块演示了 Spring Boot + Logback 的一套完整、可直接落地的日志方案:通过@Slf4j优雅地获取 logger,通过logback-spring.xml实现控制台与文件双输出,用LevelFilter与ThresholdFilter完成 INFO/ERROR 日志的分离,用TimeBasedRollingPolicy叠加SizeAndTimeBasedFNATP实现"按天 + 按大小"的双重滚动归档,并以maxHistory控制历史保留天数。掌握这套配置,即可在自己的 Spring Boot 项目中快速搭建结构清晰、易于排查问题的日志体系。
【免费下载链接】spring-boot-demo🚀一个用来深入学习并实战 Spring Boot 的项目。项目地址: https://gitcode.com/gh_mirrors/sp/spring-boot-demo
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考