1. 日志分析基础:日志的作用、日志级别与格式规范

做性能优化这些年,我越来越觉得日志就是系统的「黑匣子」。你想想看,线上出了问题,第一反应是什么?八成是「看看日志」。日志写得好,问题定位快得像开挂;日志写得烂,排查起来就像大海捞针。

这一章咱们先把地基打牢。日志的作用、级别、格式——这些看似基础的东西,其实藏着不少门道。

1.1 日志到底有什么用?

说白了,日志就是系统运行时的「录音笔」。它记录了三件事:系统在做什么、做得怎么样、出问题时是什么状态。

我个人习惯把日志的作用归纳为四个维度:

  • 故障排查:系统挂了,日志是唯一的现场证据。我记得有一次线上服务半夜 OOM,全靠 ERROR 日志里的堆栈信息锁定了内存泄漏点。
  • 性能分析:通过请求耗时日志,能快速找到慢接口、慢 SQL。我在项目中遇到过,一个接口平均响应 3 秒,翻日志发现是某个第三方调用超时重试了 3 次。
  • 监控告警:ERROR 日志数量突增,往往是故障的前兆。我曾经靠一个「5 分钟内 ERROR 数超过 100」的告警,在用户投诉前就修复了问题。
  • 审计追溯:谁在什么时间做了什么操作,日志里一清二楚。金融系统尤其看重这个。

核心观点:日志不是写给机器看的,是写给「未来的你」看的。写日志时多花 1 分钟,排查时就能省 1 小时。

1.2 日志级别:从 DEBUG 到 FATAL

日志级别这东西,很多新手容易搞混。我见过有人把所有日志都打成 INFO,也见过有人把业务异常全打成 FATAL。嗯,这里要注意——级别用错了,要么日志太多淹掉关键信息,要么漏掉真正的故障。

常见的日志级别有 5 个,从低到高:

级别 含义 使用场景 生产环境是否开启
DEBUG 调试信息 开发阶段跟踪变量、流程分支 通常关闭
INFO 一般信息 记录关键业务流程、请求入口/出口 开启
WARN 警告 潜在问题但不影响当前功能 开启
ERROR 错误 功能不可用、异常抛出 开启
FATAL 致命错误 系统即将崩溃或无法继续运行 开启

我来展开说说每个级别的用法:

DEBUG

DEBUG 日志是开发者的「放大镜」。我习惯在关键算法、复杂分支、循环内部打 DEBUG 日志。但注意——生产环境千万别开。我曾经接手过一个项目,生产环境开了 DEBUG 级别,一天产生 200GB 日志,磁盘直接打满。

INFO

INFO 是「正常流程的里程碑」。比如用户登录成功、订单创建完成、定时任务开始/结束。我个人习惯在接口入口和出口各打一条 INFO 日志,带上请求 ID 和耗时,这样排查问题时能快速串起调用链。

WARN

WARN 表示「还能忍,但最好看看」。比如配置项使用了默认值、重试机制被触发、缓存穿透。我在项目中遇到过,某个接口偶尔返回慢,查 WARN 日志发现是数据库连接池快要满了——这就是典型的「小问题变大故障」的前兆。

ERROR

ERROR 意味着「功能出问题了」。比如数据库连接失败、第三方接口返回异常、参数校验不通过。注意:ERROR 日志一定要包含足够的上下文——请求参数、堆栈信息、错误码。光打一句「系统异常」等于没打。

FATAL

FATAL 是最高级别,表示「系统要挂了」。比如内存溢出、配置加载失败、关键服务不可用。FATAL 日志通常伴随着进程退出或重启。说实话,我工作十年,FATAL 日志只见过几次,但每次都是大故障。

避坑指南:我曾经见过一个团队把所有业务异常都打成 FATAL,结果告警天天响,最后大家直接无视了所有 FATAL 日志。级别滥用比不写日志更可怕。

1.3 日志格式规范:让机器和人同时看懂

日志格式这件事,我踩过不少坑。早期做项目时,日志格式五花八门——有人用竖线分隔,有人用空格,有人连时间戳都不带。结果做日志分析时,解析脚本写得比业务代码还复杂。

一个规范的日志格式,应该满足两个要求:机器容易解析,人容易阅读。我个人推荐的结构化日志格式如下:

[时间戳] [日志级别] [线程名] [类名:行号] [请求ID] - 日志内容

举个例子:

[2025-01-15 14:23:45.678] [ERROR] [http-nio-8080-exec-3] [com.example.OrderService:156] [req-abc123] - 订单创建失败,订单号:ORD20250115001,原因:库存不足

每个字段的作用:

  • 时间戳:精确到毫秒,方便做时序分析。我习惯用 ISO 8601 格式,避免时区歧义。
  • 日志级别:快速过滤关键信息。用 grep 'ERROR' 就能定位问题。
  • 线程名:多线程环境下,能区分不同请求的日志。
  • 类名:行号:快速定位代码位置。我排查问题时,经常直接跳到对应行看代码。
  • 请求ID:这是「串联神器」。一次请求经过多个服务、多个线程,靠请求 ID 能把所有日志串起来。
  • 日志内容:包含关键业务信息,比如订单号、用户ID、错误原因。

小技巧:日志内容尽量用键值对格式,比如 orderId=ORD123, userId=U456。这样后续做日志分析时,用正则或 JSON 解析都很方便。

1.4 本章知识体系总览

下面这张图把本章的核心知识点串了起来。你可以把它当作一个「日志分析入门地图」:

日志分析基础 · 知识体系 日志 日志的作用 日志级别 日志格式规范 故障排查 性能分析 监控告警 审计追溯 DEBUG INFO WARN ERROR FATAL 时间戳 日志级别 线程名 类名:行号 请求ID 打好日志基础,后续的性能分析才能事半功倍

1.5 本章小结

这一章我们聊了三件事:

  • 日志的作用:故障排查、性能分析、监控告警、审计追溯——缺一不可。
  • 日志级别:DEBUG 到 FATAL,每个级别都有明确的适用场景。级别用对了,日志才有价值。
  • 日志格式规范:结构化、包含关键字段、内容可解析。好的格式能让后续分析工作省一半力气。