跳转至

日志与可观测性

排障不能只依靠应用日志。至少要把日志、指标、健康状态、线程栈、GC/JFR 与部署版本关联起来,才能判断问题位于 Spring 应用、JVM、容器资源还是外部依赖。

容器日志原则

容器中的应用日志优先写到 stdout/stderr,由 Docker、Kubernetes 或日志采集器统一收集;不要只写容器内部文件,否则容器重建后日志可能丢失。

日志至少包含:

时间(含时区) level service instance traceId/spanId thread logger message exception
  • 异常必须保留完整堆栈和最底层 Caused by
  • 请求日志避免打印密码、Token、Cookie、完整身份证号和请求正文。
  • 日志应带应用版本、实例和 Trace ID,便于跨服务关联。
  • DEBUG/TRACE 只临时开启,并设置恢复时间,防止磁盘、费用和敏感数据风险。

Spring Boot 日志配置示例

logging:
  level:
    root: INFO
    com.example.order: INFO
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss.SSSXXX} %-5level [%thread] %logger{36} trace=%X{traceId:-} - %msg%n"

容器平台负责轮转 stdout 日志。如果必须写文件,则要明确目录挂载、大小轮转、保留天数、压缩、磁盘告警和采集延迟,避免日志写满系统盘。

Actuator

Actuator 可提供健康、指标和日志级别等运维端点:

management:
  endpoints:
    web:
      exposure:
        include: health,info,prometheus,loggers
  endpoint:
    health:
      probes:
        enabled: true
      show-details: when_authorized
curl -s http://127.0.0.1:8080/actuator/health
curl -s http://127.0.0.1:8080/actuator/loggers/com.example

Actuator 管理端点不能直接暴露公网。envconfigprops、heapdump、logfile 和动态修改 logger 等能力可能泄露敏感信息或增加资源消耗,应通过独立管理端口、内网、认证和最小暴露列表保护。

关键指标

层次 需要关注
请求 QPS、P95/P99 延迟、4xx/5xx、超时
JVM Heap、Non-Heap、GC 次数/停顿、线程数、类加载
连接池 活跃、空闲、等待数、获取连接耗时、超时
容器 CPU、工作集内存、OOMKilled、重启次数、磁盘/网络
依赖 数据库、Redis、Kafka、HTTP 客户端的错误、延迟和连接状态

指标告诉你“什么时候、哪一层异常”,日志解释具体错误,线程栈/Heap Dump/JFR 用于深入取证。单独看其中一种经常会误判。

动态调整日志级别

Actuator loggers 端点支持运行时查看和调整 logger,但必须受鉴权控制,并记录谁在何时修改、计划何时恢复。临时 DEBUG 结束后应重置,长期配置仍回写外部配置并走发布流程。

排障时间线

发布版本/配置变更
  → 告警出现时间
  → 请求错误与延迟
  → JVM/容器资源变化
  → 外部依赖状态
  → 同时段日志、线程栈、GC/JFR

先对齐时间与实例,再分析错误;不要把不同实例、不同 Profile 或不同时区的日志拼成一条因果链。

官方参考:Actuator EndpointsLoggersMetrics