日志基础:日志级别、结构化日志与格式标准

说起来,日志这东西,没出事的时候你觉得它占磁盘,出了事你恨不得它能帮你把代码逐行重放一遍。我在早期做凭据系统的时候,就吃过一次大亏——线上一个分发服务莫名其妙报错,我翻了一整天日志,发现全是 INFO 级别,连个 ERROR 的影子都没有。嗯,后来才知道,开发同学把关键错误打成了 DEBUG 级别。

所以,今天咱们就把日志基础聊透。从级别划分到结构化,再到几个主流格式标准,把这些东西搞清楚了,后面的追踪工作才能有的放矢。

1. 日志级别:你的“报警优先级”

为什么要有日志级别?说白了,就是给每条消息标个“紧急程度”。你不可能在几十万行日志里逐行找问题,级别就是你的过滤器。

我习惯把日志级别理解成“通知的几种模式”:

  • FATAL — 系统要挂了,必须立刻人工介入。比如数据库连接池枯竭、关键配置丢失。
  • ERROR — 当前操作失败了,但系统还能继续跑。比如一次 验证请求抛异常。
  • WARN — 发生了意料之外的情况,但业务能兜底。比如重试了两次才拿到凭据。
  • INFO — 正常业务流程的关键节点。比如“用户登录成功”、“ 已签发”。
  • DEBUG — 开发调测用的细粒度信息。线上环境一般关掉,否则磁盘很快就爆了。
  • TRACE — 比 DEBUG 更细,常用来追踪一次完整请求的内部细节。

有些团队只用了 INFO 和 ERROR 两个级别。我个人觉得不够。你想想看,如果所有失败信息都用 ERROR,那正常业务的“请求失败”和系统“内存溢出”就混在一起了,没法自动触发告警。

我的习惯: 凭据相关日志至少分四级: 签发的关键路径用 INFO,验证失败用 WARN,验证异常(比如签名不匹配)用 ERROR,而详细的加解密参数只在 DEBUG 里出现。这样线上只看 ERROR 和 WARN 就够了,DEBUG 留给复现问题时开启。

2. 结构化日志:从“文本碎片”到“可解析数据”

传统的日志长什么样?大概是这样:

2024-01-15 10:23:45 ERROR Failed to validate : signature mismatch for user admin

看着还行?但你要是想统计“过去一小时里 验证失败的次数”,就得用 grep + awk 在字符串里找关键词。而且不同模块的日志格式稍微不一样,你的脚本就挂了。我遇到过,那感觉真的很痛苦。

结构化日志,就是说把这条日志拆成一组键值对,比如 JSON 格式:

{
  "timestamp": "2024-01-15T10:23:45.123Z",
  "level": "ERROR",
  "logger": "_validator",
  "message": "Signature mismatch",
  "user_id": "admin",
  "_id": "tok_abc123",
  "error_code": "SIG_MISMATCH",
  "duration_ms": 145
}

你看到了什么?字段是明确的、类型是明确的、关键是——可查询。在 ELK 或 Loki 里直接查 error_code: SIG_MISMATCH,所有相关记录秒出,不用再写正则了。

我刚开始从传统日志转到结构化日志时,总觉得多此一举。后来有一次做安全审计,需要从百万行日志里找出某个特定用户的所有 操作记录。用传统方式搞了三个小时,用结构化日志 + 查询语句,三分钟搞定。嗯,真香。

核心原则: 结构化日志里,每个字段都应该有明确语义。避免把多个信息拼在一个字符串里。比如不要写 "user=admin,=tok_abc",应该拆成 user_id 和 _id 两个独立字段。

3. 日志格式标准:JSON 与 CEF

既然要结构化,就得有个大家都认的格式。我碰到过两种主流标准,也踩过它们的坑。

3.1 JSON 格式

JSON 是目前最通用的结构化日志格式。优点很明显:人人能读,大多数日志收集系统原生支持嵌套结构,解析成本低。

  • 适用场景: 应用日志、API 网关日志、微服务调用链。
  • 常见字段: timestamp、level、logger、message、context(嵌套结构放 request_id、user_id 等)。
  • 注意点: 不要塞太多深层嵌套,否则解析性能会下降。我见过有人把完整的 HTTP 请求体都丢进去,结果 ELK 集群 CPU 直接爆了。

3.2 CEF(Common Event Format)

CEF 是 ArcSight 提的标准,常见于安全设备和 SIEM 集成。它的特点是“固定前缀 + 键值扩展”,格式大概长这样:

CEF:0|MyVendor|TokenService|1.0|100| validation failed|5|src=192.168.1.1 dst=10.0.0.1 user=admin msg=Signature mismatch

我刚开始接触 CEF 时觉得它很“古老”,但做安全日志对接时发现,很多 SIEM 工具原生解析 CEF,比 JSON 还快。如果你需要把 操作日志直接喂给安全分析平台,CEF 是值得掌握的。

下面这张表我用得比较多,在方案设计时通常会用它来对比两种格式的差异:

维度 JSON CEF
可读性 好,人机都友好 一般,字段多时很紧凑
解析性能 中等,需要递归解析 高,固定前缀位置明确
安全生态 通用,所有工具都支持 ArcSight、QRadar 等 SIEM 原生支持
复杂结构 支持嵌套 只能键值对,不支持嵌套
扩展性 自由添加新字段 需要遵守预定义扩展键

我的建议是:内部系统优先用 JSON,灵活且好查;需要跟安全平台对接时,再考虑 CEF。如果你想两全,可以在应用层输出 JSON,然后用 Logstash 或 Fluentd 转成 CEF 发送给 SIEM。

避坑指南(我吃过亏): 曾经我直接在生产环境改了日志格式,从纯文本切到 JSON,结果日志收集器还没更新配置,导致日志全部丢失。所以,切换格式时最好加个双写过渡期,或者先灰度一小部分实例。

本章知识结构图

下面这张图把咱们聊的内容串起来。从原始日志产生,到级别筛选,再到结构化,最后落到具体的格式标准上。

日志基础:结构化与格式核心路径 日志原始事件 FATAL / ERROR WARN / INFO DEBUG / TRACE 结构化日志:时间 + 级别 + 字段键值对 JSON 格式(通用) CEF 格式(安全生态) 日志收集与分析(ELK / Loki / SIEM) 结构化的核心价值:让日志从“字符串”变成“可查询的字段”,大幅提升追踪效率

嗯,上面这张图把咱们聊的“日志级别筛选 → 结构化改造 → 格式落地”这条线串起来了。你在做凭据日志追踪时,可以照着这个思路搭自己的日志体系:先定级别,再写结构化,最后选格式。每一步都不复杂,但组合起来效果很不一样。