日志与可观测性¶
排障不能只依靠应用日志。至少要把日志、指标、健康状态、线程栈、GC/JFR 与部署版本关联起来,才能判断问题位于 Spring 应用、JVM、容器资源还是外部依赖。
容器日志原则¶
容器中的应用日志优先写到 stdout/stderr,由 Docker、Kubernetes 或日志采集器统一收集;不要只写容器内部文件,否则容器重建后日志可能丢失。
日志至少包含:
- 异常必须保留完整堆栈和最底层
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 管理端点不能直接暴露公网。env、configprops、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 结束后应重置,长期配置仍回写外部配置并走发布流程。
排障时间线¶
先对齐时间与实例,再分析错误;不要把不同实例、不同 Profile 或不同时区的日志拼成一条因果链。
官方参考:Actuator Endpoints、Loggers、Metrics。