SLF4J 与 Logback
约 1080 字大约 4 分钟
布欧-Lewyon
2026-05-15
首页 › Java › 日志 › SLF4J 与 Logback
日志体系在 Java 中分两层:门面(facade)提供统一的 API,实现(implementation)负责实际的日志输出。SLF4J(Simple Logging Facade for Java)是最广泛使用的门面,Logback 是它的原生实现且功能强大。
门面模式
应用程序代码 → SLF4J API → Logback(实现)
→ Log4j 2(另一种实现)
→ java.util.logging代码只依赖 SLF4J 的 API,不直接引用 Logback 的具体类。切换日志框架时只需替换 pom.xml 中的实现依赖,业务代码无需改动。
Maven 依赖
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.11</version>
</dependency>logback-classic 自动引入 slf4j-api 和 logback-core,一个依赖搞定。
基本用法
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class OrderService {
private static final Logger log = LoggerFactory.getLogger(OrderService.class);
public void createOrder(String userId, double amount) {
log.info("创建订单: userId={}, amount={}", userId, amount);
try {
// 业务逻辑
} catch (Exception e) {
log.error("订单创建失败: userId={}", userId, e);
}
}
}LoggerFactory.getLogger(类名)获取 Logger 实例,建议private static final。- SLF4J 的占位符
{}替代字符串拼接——仅当日志级别满足输出条件时才格式化,避免无谓开销。 - 异常对象作为最后一个参数传入,保留堆栈轨迹。
日志级别
| 级别 | 用途 |
|---|---|
ERROR | 不可恢复的错误,需要立即关注 |
WARN | 潜在问题,不影响核心功能 |
INFO | 关键业务流程节点(订单创建、用户登录等) |
DEBUG | 开发/排查时的详细信息,生产环境通常关闭 |
TRACE | 比 DEBUG 更细的追踪信息 |
ERROR > WARN > INFO > DEBUG > TRACE设置级别后,高于或等于该级别的方法才会输出。生产环境通常设 INFO,开发环境设 DEBUG。
Logback 配置
Logback 在 classpath 根目录找配置文件,优先级:logback-test.xml > logback.xml。
最小配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 控制台输出 -->
<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>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
</root>
</configuration>pattern 格式说明:
| 占位符 | 含义 |
|---|---|
%d | 日期时间 |
%thread | 当前线程名 |
%-5level | 日志级别(左对齐 5 字符) |
%logger{36} | Logger 名(缩写超长部分) |
%msg | 日志消息 |
%n | 换行 |
文件输出与滚动
<appender name="FILE" class="ch.qos.logback.core.rolling.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{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root>按包设置级别
不同包使用不同的日志级别,对框架类库通常设为 WARN 减少噪音:
<logger name="com.example.myapp" level="DEBUG"/>
<logger name="org.springframework" level="WARN"/>
<logger name="org.hibernate" level="WARN"/>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
</root>MDC:映射诊断上下文
MDC(Mapped Diagnostic Context)在同一个请求/线程内传递上下文信息(如 traceId、userId),日志 pattern 中引用后自动输出:
import org.slf4j.MDC;
public void handleRequest(String traceId) {
MDC.put("traceId", traceId);
try {
log.info("处理请求"); // 自动带上 traceId
// ...
} finally {
MDC.clear(); // 务必清理
}
}配置中引用 MDC:
<pattern>%d [%thread] %-5level [%X{traceId}] %logger{36} - %msg%n</pattern>日志分离:按包输出到不同文件
<!-- 将安全审计日志单独输出到 audit.log -->
<appender name="AUDIT" class="ch.qos.logback.core.FileAppender">
<file>logs/audit.log</file>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} - %msg%n</pattern>
</encoder>
</appender>
<logger name="com.example.audit" level="INFO" additivity="false">
<appender-ref ref="AUDIT"/>
</logger>additivity="false" 阻止日志向上传递给 root logger,避免重复输出。
小结
- SLF4J 是日志门面,Logback 是推荐实现;代码只引
org.slf4j.Logger。 log.info("参数: {}", value)使用占位符,避免字符串拼接开销。- 日志级别 ERROR → TRACE 由高到低;生产通常
INFO,开发DEBUG。 - Logback 配置文件支持控制台、滚动文件、按包设置级别。
- MDC 在请求线程中传递上下文(traceId/userId),在 pattern 中用
%X{key}输出。 - 易错:
log.error("消息", exception)和log.error("消息: {}", exception.getMessage())的区别——前者打印完整堆栈,后者只记录消息,丢失了排查问题最关键的信息。始终将异常对象作为最后一个参数传入。 - 思考任务:为应用配置 Logback,实现:控制台输出 DEBUG 级别,每天滚动的文件输出 INFO 级别且保留 7 天,按包将
com.example.audit的日志单独输出到audit.log。
上一节:参数化测试与 Mock
下一节:HTTP 与 REST
