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。

结合场景再看三个关注点

  1. 生产优先 SLF4J API(示例用 JUL 仅因零依赖可演示)。
  2. 级别:ERROR/WARN/INFO/DEBUG。
  3. 敏感数据脱敏

核心概念与准确模型

1. 门面 vs 实现

  • 门面稳定 API
  • 实现负责输出、异步、滚动

2. 结构化

JSON 日志 + traceId/userId

3. 配置

classpath 上 logback.xml 等;级别可动态调。

边界情况与反直觉行为

  1. 错误日志打两次(框架+业务)。
  2. DEBUG 在热路径巨量分配。
  3. 丢弃异常对象只打消息。

常见误区

[!warning] 常见误区:e.printStackTrace() 难重定向、难关联请求;走日志框架。

工程实践

  1. 统一门面。
  2. 每个请求相关日志带 correlation id。
  3. 访问日志与应用日志分工。
  4. 采样与级别策略防爆盘。

本节总结

  • 门面+实现
  • 级别+字段
  • 为可观测打底

自测题

  1. 为什么要用参数化 log.info("x={}", id)
  2. WARN 与 ERROR 如何粗分?
参考答案
  1. 未启用该级别时可避免无用拼接;实现也可更好布局。
  2. ERROR:需立即关注的失败;WARN:异常但可恢复/降级。

延伸阅读与资料来源

资料类型支撑内容
SLF4J Manual官方门面
java.util.loggingAPIJDK 日志
创建于 2026/7/15 更新于 2026/7/15