Java 日志
日志门面与实现、级别与结构化字段:如何让排障信息可检索且可控量。
#type / concept
#status / growing
#tech / dev
#resource / java
[!info] 关联笔记
Java 日志
这个概念为什么出现
生产不能靠 System.out。日志提供运行轨迹:请求 id、错误栈、关键业务字段。Java 生态常见 门面(SLF4J)+ 实现(Logback/Log4j2)。
[!abstract] 一句话理解 业务代码依赖日志门面;级别控制噪音;用参数化消息与关联 ID,让日志可检索并避免无用字符串拼接成本。
最小可运行示例
场景:下单失败时记录可检索错误
import java.util.logging.Level;
import java.util.logging.Logger;
public class OrderLogDemo {
private static final Logger log = Logger.getLogger(OrderLogDemo.class.getName());
static void place(String orderId, boolean ok) {
if (!ok) {
// 参数化/字段化:至少包含业务主键
log.log(Level.WARNING, "place failed orderId={0}", orderId);
return;
}
log.info(() -> "place ok orderId=" + orderId);
}
public static void main(String[] args) {
place("ORD-1", false);
place("ORD-2", true);
}
}
建议运行:
javac OrderLogDemo.java && java OrderLogDemo
期望:警告与 info 行均出现且含 orderId。
结合场景再看三个关注点
- 生产优先 SLF4J API(示例用 JUL 仅因零依赖可演示)。
- 级别:ERROR/WARN/INFO/DEBUG。
- 敏感数据脱敏。
核心概念与准确模型
1. 门面 vs 实现
- 门面稳定 API
- 实现负责输出、异步、滚动
2. 结构化
JSON 日志 + traceId/userId
3. 配置
classpath 上 logback.xml 等;级别可动态调。
边界情况与反直觉行为
- 错误日志打两次(框架+业务)。
- DEBUG 在热路径巨量分配。
- 丢弃异常对象只打消息。
常见误区
[!warning] 常见误区:e.printStackTrace() 难重定向、难关联请求;走日志框架。
工程实践
- 统一门面。
- 每个请求相关日志带 correlation id。
- 访问日志与应用日志分工。
- 采样与级别策略防爆盘。
本节总结
- 门面+实现
- 级别+字段
- 为可观测打底
自测题
- 为什么要用参数化
log.info("x={}", id)? - WARN 与 ERROR 如何粗分?
参考答案
- 未启用该级别时可避免无用拼接;实现也可更好布局。
- ERROR:需立即关注的失败;WARN:异常但可恢复/降级。
延伸阅读与资料来源
| 资料 | 类型 | 支撑内容 |
|---|---|---|
| SLF4J Manual | 官方 | 门面 |
| java.util.logging | API | JDK 日志 |