日志怎么打才专业?Spring Boot 4 日志体系与 Logback 配置(生产级实战)

本篇是《Spring Boot 4 学习从入门到大神》专栏第 5 篇。

很多项目"能跑,但日志一塌糊涂"。本文将彻底讲清 Spring Boot 4 的日志架构、Logback 配置、日志分级、文件滚动和生产环境最佳实践,帮你写出可排查、可审计、可运维的日志。


一、Spring Boot 4 日志体系全景图

Spring Boot 4 默认日志方案

复制代码
SLF4J → Logback

1️⃣ 为什么是 SLF4J?

SLF4J 只是一个日志门面,不是实现。

✅ 好处:

  • 不绑定具体日志框架

  • 随时切换实现(Log4j2 / Logback)

  • 代码无侵入

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;

    public class DemoService {
    private static final Logger log = LoggerFactory.getLogger(DemoService.class);
    }

📌 永远不要直接 import logbacklog4j 的类!


2️⃣ Spring Boot 4 默认实现:Logback

Spring Boot Starter 中已内置:

复制代码
spring-boot-starter-logging

它包含:

  • SLF4J

  • Logback

  • 桥接器(jul-to-slf4j、log4j-to-slf4j)

✅ 你什么都不用配,日志就能用。


二、日志级别(必须分清)

Spring Boot 4 支持以下级别(从低到高):

级别 使用场景
TRACE 最细粒度,调试底层
DEBUG 开发调试
INFO 关键业务节点(推荐)
WARN 潜在问题
ERROR 错误,但系统还能跑
FATAL 严重错误,系统即将崩溃(Logback 不常用)

📌 生产环境默认级别:INFO


三、最简单也最正确的打日志方式

✅ 推荐写法(占位符)

复制代码
log.info("用户 {} 登录成功,IP={}", userId, ip);

❌ 错误写法(字符串拼接)

复制代码
log.info("用户 " + userId + " 登录成功,IP=" + ip);

❌ 缺点:

  • 即使日志级别不生效,字符串也会拼接

  • 影响性能


四、Spring Boot 4 日志基础配置(application.yml)

1️⃣ 全局日志级别

复制代码
logging:
  level:
    root: INFO
    com.example.demo: DEBUG
    org.springframework: WARN

✅ 含义:

  • 全局:INFO

  • 自己项目:DEBUG

  • Spring 框架:WARN


2️⃣ 输出到文件(生产必配)

复制代码
logging:
  file:
    name: logs/app.log
  format:
    pattern:
      file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger - %msg%n"

📌 不要只打控制台日志!


五、为什么默认配置不够用?(生产痛点)

默认配置的问题:

  • ❌ 日志文件无限增长

  • ❌ 不按日期切割

  • ❌ 不压缩

  • ❌ 排查问题时找不到日志

👉 生产环境必须使用 logback-spring.xml


六、生产级 logback-spring.xml 配置(重点)

src/main/resources 下创建:

复制代码
logback-spring.xml

✅ 完整示例(可直接复制)

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

    <!-- 引入 Spring Boot 默认配置 -->
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>

    <!-- 日志文件路径 -->
    <property name="LOG_PATH" value="logs"/>
    <property name="APP_NAME" value="spring-boot4-demo"/>

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

    <!-- 文件输出(按天滚动) -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_PATH}/${APP_NAME}.log</file>

        <!-- 滚动策略 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 按天归档 -->
            <fileNamePattern>${LOG_PATH}/${APP_NAME}.%d{yyyy-MM-dd}.log.gz</fileNamePattern>
            <!-- 保留 30 天 -->
            <maxHistory>30</maxHistory>
            <!-- 总大小不超过 3GB -->
            <totalSizeCap>3GB</totalSizeCap>
        </rollingPolicy>

        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!-- 异步日志(提升性能) -->
    <appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="FILE"/>
        <!-- 队列满时丢弃 TRACE、DEBUG -->
        <discardingThreshold>0</discardingThreshold>
        <queueSize>512</queueSize>
    </appender>

    <!-- 环境隔离:dev 只打控制台 -->
    <springProfile name="dev">
        <root level="INFO">
            <appender-ref ref="CONSOLE"/>
        </root>
    </springProfile>

    <!-- 生产环境:文件 + 异步 -->
    <springProfile name="prod">
        <root level="INFO">
            <appender-ref ref="CONSOLE"/>
            <appender-ref ref="ASYNC_FILE"/>
        </root>
    </springProfile>

</configuration>

七、这个配置强在哪?(重点理解)

按天滚动app.2026-01-15.log.gz

自动压缩:节省磁盘

自动清理:只保留 30 天

异步写日志:不阻塞业务线程

环境隔离:dev / prod 不同策略


八、多环境日志配置(Spring Boot 4 特色)

利用 springProfile

复制代码
<springProfile name="dev">
    <!-- 开发环境 -->
</springProfile>

<springProfile name="prod">
    <!-- 生产环境 -->
</springProfile>

比 application.yml 更灵活


九、日志打印的最佳实践(非常重要)

✅ 1️⃣ 哪些必须打日志?

  • 系统启动 / 关闭

  • 关键业务操作(下单、支付、登录)

  • 外部接口调用(入参 + 出参)

  • 异常堆栈(不要吞掉)


✅ 2️⃣ 哪些不要打?

❌ 敏感信息(密码、身份证、Token)

❌ 大对象(JSON 全量打印)

❌ 高频循环内打日志


✅ 3️⃣ 异常日志怎么打?

❌ 错误写法:

复制代码
log.error("出错了:" + e.getMessage());

✅ 正确写法:

复制代码
log.error("用户 {} 下单失败", userId, e);

📌 一定要把异常对象传进去!


十、Spring Boot 4 中的日志新变化

  • 日志初始化更早(AOT 模式)

  • 对 GraalVM 原生镜像支持更好

  • 日志桥接器默认更严格(防止冲突)


十一、常见坑位总结

❌ 坑1:日志文件把磁盘打满

✅ 解决:配置滚动策略 + 总大小限制


❌ 坑2:生产环境只打控制台

✅ 解决:必须输出到文件


❌ 坑3:异常没堆栈

✅ 解决:log.error("msg", e)


❌ 坑4:直接使用 System.out.println

✅ 解决:统一用 SLF4J


十二、本篇总结(记住这 5 句话)

  1. Spring Boot 4 = SLF4J + Logback

  2. 生产环境必须写日志文件

  3. 日志要滚动、压缩、清理

  4. 异步日志提升性能

  5. 异常日志一定要带堆栈

相关推荐
mldong10 小时前
C# 开发者也有自己的轻量工作流引擎了:NuGet 装包,5 分钟跑通一条审批流
后端·c#·.net
xcl092511 小时前
幼儿托育系统开发实战:从需求分析到上线全流程指南
java·大数据·需求分析
吴声子夜歌11 小时前
ApacheCommons——commons-cli(命令行参数解析)
java·开发语言·apache
小小猪的春天11 小时前
Java 手写第一个 MCP Server:Spring AI MCP 半小时跑通
java·人工智能·spring boot·ai编程
find1star11 小时前
LeetCode 141:环形链表
java·算法·leetcode·链表
爱学堂IT分享12 小时前
鹤翔老师pmp项目管理培训认证考试课 (直播录播题库送学时证明)【共58课时】-51CTO学堂
后端
今天AI了吗12 小时前
DeepSeek Harness 深度解析:从评测架构到实战落地
java·网络·数据库·人工智能·架构·java-ee
王的宝库12 小时前
Go 项目结构:从单文件到标准工程布局
开发语言·后端·golang
许彰午12 小时前
27-AuthService登录链路
java·低代码·架构
泡海椒12 小时前
JQuick-Curl 性能分析:并发场景下的性能表现与调优,第三方接口调用不只要快写也要稳跑
java·开发语言·okhttp