8
日志:Logback 与 SLF4J
Logging
Spring Boot 默认用 SLF4J(门面)+ Logback(实现)。你不用选日志框架,开箱即用。记住一个原则:永远面向 SLF4J 写代码,别直接 new Logback 的类,将来想换 Log4j2 只改依赖不改代码。
代码里打日志
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TaskService {
private static final Logger log = LoggerFactory.getLogger(TaskService.class);
public void create() {
log.debug("创建任务,参数={}", args); // 占位符 {} 别用字符串拼接
log.info("任务创建成功");
log.warn("任务标题过长");
log.error("保存失败", e); // 异常对象放最后一个参数,自动打栈
}
}
application.yml 调日志级别
logging:
level:
root: INFO # 全局默认级别
com.example.demo: DEBUG # 自己的包开 DEBUG
org.hibernate.SQL: DEBUG # 想看 SQL 就开这个
自定义 logback-spring.xml(resources 下)
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 控制台输出格式 -->
<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 name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>app.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE"/>
</root>
</configuration>
文件名必须叫 logback-spring.xml 而不是 logback.xml——前者能识别 Spring 的 profile 标签,按环境加载不同日志配置。
为什么默认 Logback?什么时候换 Log4j2
Boot 默认用 Logback(SLF4J 亲儿子)。但高并发、日志量大的系统,团队会切到 Log4j2——它的异步 Appender 用 LMAX Disruptor 无锁队列,吞吐明显更高。
| 日志实现 | 特点 / 适用 |
|---|---|
| Logback(默认) | 和 SLF4J 原生集成、配置简单、够用。绝大多数项目用它就行。 |
| Log4j2 | 异步日志性能强、支持插件化配置。注意:老版本有 log4shell 漏洞(CVE-2021-44228),用它必须升到最新版。以官网最新稳定版为准。 |
<!-- 想换 Log4j2:先排除默认 logback,再引入 starter-log4j2 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
本章面试题 · 第 8 章(日志)
1.(概念题)SLF4J 和 Logback 是什么关系?为什么不能直接用 System.out.println?
查看答案
答案:SLF4J 是日志门面(抽象接口),Logback 是它的实现。业务代码只调 SLF4J 的 API,底层换 Log4j2 等不用改代码。System.out.println 没有级别、没有异步、没有归档,生产环境不能用。解析:记住"门面 + 实现"这对关系,和 JDBC/驱动一个思路。
2.(实践题)怎么在生产环境把某一个包的日志调成 DEBUG?
查看答案
答案:application.yml 里 logging.level.com.example=debug,或动态通过 Actuator /loggers 端点调整(不用重启)。解析:线上排查问题时这个技能很实用。