Administrator
发布于 2024-05-22 / 7484 阅读
61

Spring Boot 3.4 结构化日志与可观测性增强

有天凌晨告警:订单服务报错率突增。我登录 Kibana 翻日志,几千行文本里找那一条异常,正则写到手抖,花了 20 分钟才定位。痛定思痛,把日志从"人看"改成"机器看"——结构化输出,这套改造后来的排障时间从 20 分钟降到 40 秒。

为什么要从文本日志切到结构化

文本日志是给人扫的,机器分析要正则硬抠,字段一变就全废。结构化日志(JSON / ECS)把每行变成带字段的键值对,对接 Loki、Elasticsearch 直接按字段聚合。Spring Boot 3.4 引入的结构化日志让这事儿零依赖:不用再引 Logstash encoder 那一套。

结构化日志输出配置

application.yml 里指定格式即可:

logging:
  structureded:
    format:
      console: elasticsearch  # 可选 ecs、logstash
  level:
    root: info
    com.acme.order: debug

输出从这样:

2024-05-22 13:59:01.123 INFO  [order-svc,abc123] c.a.o.Service - 下单成功 orderId=8891

变成这样:

{"@timestamp":"2024-05-22T13:59:01.123Z","level":"INFO","service":"order-svc","traceId":"abc123","logger":"c.a.o.Service","message":"下单成功","orderId":"8891"}

字段稳定、可索引,按 orderId 一搜就出。

OTLP 集成:日志直接进可观测后端

光输出 JSON 不够,要能传走。我们接了 OpenTelemetry 协议(OTLP),日志、指标、链路统一出口:

otel:
  logs:
    exporter: otlp
  exporter:
    otlp:
      endpoint: http://otel-collector:4317
      protocol: grpc

配合 Micrometer,指标也走 OTLP。以前 Prometheus 拉 + 日志另外推,两套管道;现在统一 OTLP 推给 Collector,再由它分流到 Prometheus(指标)、Loki(日志)、Tempo(链路)。部署复杂度降了一截。

一个收益对比

场景文本日志+正则结构化+字段检索
按 orderId 查一条日志约 20 分钟(翻页+正则)40 秒
统计每分钟错误率几乎做不到1 条聚合查询
字段变更兼容性正则全废新增字段自动索引

Actuator 增强:把内部状态亮出来

Spring Boot 3.4 的 Actuator 在 /actuator 下多了些端点,我们重点用三个:

  • /actuator/metrics:直接看 JVM、HTTP 请求耗时分布,不用额外埋点;
  • /actuator/threaddump:虚拟线程时代线程数暴增,这里能看到平台线程与虚拟线程比例;
  • /actuator/loggers:运行时动态调日志级别,线上排查时把某个包调到 debug,完事调回,不用重启。

我们把 /actuator/loggers 接了内部运维平台,点一下按钮就能给某个服务开 debug 日志,救过不止一次火。

踩坑

  • 性能:JSON 序列化比文本慢一截,高 QPS 服务开启后 CPU 涨了约 8%。我们用异步 Appender 削峰,控制在 3% 内;
  • 敏感字段:message 里别带手机号、 token,上线前加了脱敏转换器;
  • 磁盘:结构化日志体积大 30%,日志轮转周期从 7 天缩到 3 天,配合远端存储。

小结

结构化日志 + OTLP 把"排障靠肉眼"升级为"排障靠查询"。Spring Boot 3.4 把它做成开箱即用,配置成本极低。Actuator 的动态日志级别和指标端点,是线上救火的利器。代价是少许 CPU 和存储,换来的是故障定位时间的数量级下降——这笔账怎么算都值。别等半夜被告警叫醒才想起该结构化。

参考