日志是排查问题时唯一的时光机。但大部分项目的日志要么太少找不到线索,要么太多找不到重点。聊聊怎么打。
原则一:每条日志要有明确的目的 打之前问自己:这条日志是为了回答什么问题?
- 「用户 X 登录失败」→ 回答安全审计问题。
- 「订单 Y 状态从 A 变为 B」→ 回答状态流转问题。
- 「调用外部服务 Z 耗时 3.2s」→ 回答性能问题。
答不上来目的的日志,删掉。
原则二:结构化 纯文本日志没法聚合分析。用 JSON 格式输出,字段固定:
- timestamp(ISO 8601,带时区)
- level
- trace_id / request_id
- 业务标识(user_id、order_id)
- 事件名
- 上下文参数
有了结构化日志,「过去一小时某个接口的平均耗时」这种问题一条查询语句就能回答,不用去 grep。
原则三:trace_id 贯穿全链路 分布式系统里,一个请求会经过多个服务。没有统一的 trace_id,出问题时你无法把散落在各处的日志串起来。
做法:在入口层生成 trace_id,通过 HTTP header 或消息属性往下传,每个服务都把它打进日志。
原则四:日志级别要用对
- ERROR:需要人工介入的问题。系统无法自行恢复。
- WARN:异常但可恢复。比如下游超时后走了降级。
- INFO:关键的业务事件和状态变更。
- DEBUG:调试信息,生产环境默认关闭。
最常见的错误是把所有异常都打成 ERROR。结果 ERROR 日志泛滥,真正的问题被淹没,告警也变成噪音。
原则五:不要打敏感信息 密码、token、身份证号、银行卡号、完整手机号——这些一旦进日志,就是数据泄露风险。
做法:
- 在日志框架层面做脱敏,而不是靠开发者自觉。
- 对敏感字段做掩码(手机号中间四位打星)。
- 定期审计日志内容。
原则六:控制体积 日志的成本不只是存储。海量的日志会让检索变慢,让真正重要的信息被埋掉。
- 循环里不要打日志。
- 高频接口的 INFO 日志要考虑采样。
- 设置合理的保留期(热数据 7-30 天,冷数据归档)。
一个自查方法 随便挑一个线上问题,看能不能只靠日志在 5 分钟内定位。如果做不到,日志就需要改进。
本文由奇幻维度内容助手整理发布,欢迎在评论区交流你的看法。