大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
日志框架
System.out.println 排障一次还行,上线后你需要 级别、格式、滚动文件与集中采集。Java 生态的标准答案是 SLF4J 门面 + Logback / Log4j2 实现——spring-boot-essentials 默认如此;本课让你在脱离 Spring 时也能正确配置,并与 java-core-essentials 的异常栈追踪配合。
学习目标
- 用 SLF4J API 写日志,理解门面与实现分离
- 配置 Logback 的控制台与按日滚动文件
- 区分 DEBUG/INFO/WARN/ERROR 的使用场景,避免日志噪音与敏感信息泄露
SLF4J 基本用法
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PaymentService {
private static final Logger log = LoggerFactory.getLogger(PaymentService.class);
public void charge(String orderId, long amountCents) {
log.info("charge start orderId={} amount={}", orderId, amountCents);
try {
// ... 调用支付网关
log.debug("gateway response received orderId={}", orderId);
} catch (Exception ex) {
log.error("charge failed orderId={}", orderId, ex);
throw ex;
}
}
}
占位符 {} 优于字符串拼接:实现层可延迟 toString(),且避免 null 拼接 NPE。
Logback 配置(logback.xml)
<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>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/app.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>14</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d ISO8601 [%thread] %-5level %logger - %msg%n</pattern>
</encoder>
</appender>
<logger name="com.example.payment" level="DEBUG"/>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
</configuration>
门面 vs 实现 vs 竞品
| 组件 | 角色 |
|---|---|
| SLF4J | 应用代码只依赖此 API |
| Logback | Spring Boot 默认实现,与 SLF4J 同作者 |
| Log4j2 | 高性能替代,需 log4j-slf4j2-impl 桥接 |
| Tinylog | 极简依赖,适合 Android/CLI,API 不同 |
禁止在业务代码里直接 import org.apache.logging.log4j.Logger——换实现时要改全库。
最佳实践
- 生产默认 INFO;排障时临时调高包级别,而非永久 DEBUG
- 结构化字段:订单号、traceId 用 key=value,便于 ELK/Loki 检索
- 不要打密码、token、完整卡号;PII 需脱敏
- 异常用
log.error("msg", ex)保留栈,不要只ex.getMessage()
练习
- 为 jev-db 的
UserRepository加 INFO(成功)与 ERROR(SQL 异常)日志 - 写 logback.xml,验证日志同时输出控制台与
logs/app.log - 用
<logger name="org.hibernate.SQL" level="DEBUG"/>观察 ORM SQL,再改回 WARN
小结
SLF4J 写代码,Logback 配输出;级别与格式决定线上可观测性。 下一课用 Javadoc 把 API 契约写进源码。