2、日志格式规范:让每一条日志都成为线索
日志格式这事,说大不大,说小不小。我见过太多团队,日志写得随心所欲,检索的时候恨不得把键盘砸了。说白了,日志格式就是你和未来自己之间的约定——你希望三个月后的你,能一眼看懂今天写的日志吗?
核心观点:日志格式不是给机器看的,是给人看的。格式统一了,检索才有意义。
2.1 通用日志格式:五个字段,一个都不能少
我个人习惯,任何日志至少包含五个字段:时间戳、级别、线程、类名、消息。这五个字段就像身份证上的信息,缺了哪个都不好查。
| 字段 | 含义 | 示例 | 为什么重要 |
|---|---|---|---|
| 时间戳 | 日志产生的时间 | 2025-03-21 14:30:00.123 |
定位问题发生的时间点,排查性能瓶颈必备 |
| 级别 | 日志的严重程度 | ERROR / WARN / INFO |
快速过滤关键信息,别让INFO淹没了ERROR |
| 线程 | 执行日志的线程名 | http-nio-8080-exec-3 |
多线程环境下追踪请求链路,谁干了什么一目了然 |
| 类名 | 产生日志的类 | com.example.OrderService |
快速定位代码位置,不用翻源码猜 |
| 消息 | 具体的日志内容 | 订单创建成功,订单号:ORD123456 |
核心信息,必须包含关键业务标识 |
举个例子,一个标准的日志行长这样:
2025-03-21 14:30:00.123 [http-nio-8080-exec-3] ERROR com.example.OrderService - 订单创建失败,订单号:ORD123456,原因:库存不足
嗯,这里要注意:时间戳一定要带毫秒。我在项目中遇到过,排查一个性能问题,日志只精确到秒,结果同一秒内几十个请求混在一起,根本分不清先后顺序。加了毫秒之后,问题瞬间清晰了。
小技巧:时间戳统一用 ISO 8601 格式(yyyy-MM-dd HH:mm:ss.SSS),跨系统、跨语言解析都方便。别用自定义格式,比如 2025/03/21 14:30:00,解析起来麻烦。
2.2 自定义日志格式:按需扩展,别过度设计
通用格式够用吗?说实话,大部分场景够了。但有些时候,你需要加点料。比如微服务架构下,你得知道这条日志来自哪个服务实例;再比如处理用户请求时,你得能串联起整个调用链。
我建议,自定义字段遵循一个原则:不加则已,加必有因。每加一个字段,都要问自己:这个字段在检索时真的会用吗?
常见的自定义字段包括:
- 请求ID(traceId):串联一次请求的所有日志,微服务排障利器
- 用户ID(userId):快速定位某个用户的操作记录
- 服务名(serviceName):分布式环境下区分日志来源
- 环境标识(env):区分开发、测试、生产环境
举个例子,加上自定义字段后的日志:
2025-03-21 14:30:00.123 [http-nio-8080-exec-3] ERROR com.example.OrderService - [traceId=a1b2c3d4] [userId=10086] [env=prod] 订单创建失败,订单号:ORD123456,原因:库存不足
你看,多了几个字段,检索的时候就能按 traceId 把所有相关日志串起来。我曾经排查过一个线上问题,没有 traceId,只能靠时间戳和关键词硬猜,花了整整一个下午。后来加了 traceId,类似问题十分钟搞定。
避坑指南:自定义字段不要塞太多。我曾经见过一个团队,日志里塞了十几个自定义字段,结果日志行长得像裹脚布,不仅影响写入性能,检索时也眼花缭乱。记住:字段越多,维护成本越高。
2.3 日志字段设计原则:少即是多,稳即是快
设计日志字段,说白了就是做减法。我总结了四条原则,你可以直接拿来用。
- 唯一性原则:每条日志必须能唯一标识一个业务实体。比如订单号、用户ID、请求ID,至少有一个。
- 可检索原则:字段值要方便检索。避免用长文本、JSON 嵌套、特殊字符。比如消息里不要写
订单创建失败,原因:{"code":1001,"msg":"库存不足"},直接写订单创建失败,原因:库存不足更友好。 - 稳定性原则:字段名和字段类型一旦确定,不要轻易改。改了之后,历史日志的检索就断了。我见过一个项目,日志字段从
userId改成user_id,结果历史数据全废了。 - 最小化原则:只记录必要信息。别把整个请求体、响应体都塞进日志。日志量太大,存储和检索都是成本。
一句话总结:日志字段设计,就像收拾行李箱——能带上的才带,带不上的就别硬塞。
2.4 日志格式规范知识体系
下面这张图,把日志格式规范的核心内容串起来了。你可以把它当作一个检查清单,每次设计日志格式时对照一下。
2.5 实战建议:从今天开始改
如果你现在的日志格式还很混乱,别慌。我建议你分三步走:
- 第一步:统一通用格式。先把时间戳、级别、线程、类名、消息这五个字段对齐。这是底线,不能妥协。
- 第二步:按需加自定义字段。先加 traceId 和 userId,这两个最常用。其他字段等确实需要了再加。
- 第三步:写一份日志规范文档。把格式、字段定义、示例都写清楚,团队所有人都按这个来。我见过太多团队,口头约定一套,写出来又是另一套。
最后说一句:日志格式规范这件事,越早做越好。等日志量上去了再改,成本高得吓人。你想想看,是现在花半天时间统一格式划算,还是以后花一周时间重构日志系统划算?