3、故障信息收集:日志收集与监控数据采集
故障发生的那一刻,说实话,最怕的不是问题有多复杂,而是你手里没数据。
我见过太多这样的场景:线上告警响了,一群人围过来,你问「日志呢?」——没人采集。你问「监控呢?」——指标断了。你问「最近改了什么?」——大家面面相觑。这种时候,再厉害的分析方法也白搭。
所以,信息收集是根因分析的第一步,也是决定成败的一步。我个人习惯把信息收集分成三大块:日志、监控、上下文。咱们一个一个说。
3.1 日志收集:应用日志、系统日志、中间件日志
日志是故障现场的第一手资料。但很多人有个误区——以为只要把日志捞出来就行。其实不是,你得知道该捞什么、从哪里捞、怎么捞。
3.1.1 应用日志
应用日志是最直接的。它记录了业务代码的执行轨迹。我建议你关注这几个关键点:
- 错误堆栈:异常类型、行号、调用链。别只看最后一行,往上翻几行往往才是真凶。
- 关键参数:入参、出参、耗时。有时候问题不是报错了,而是参数传错了。
- 时间戳:精确到毫秒。我遇到过两次故障,日志时间差了1秒,结果排查方向完全反了。
重要提醒:应用日志一定要有统一的格式。我见过最头疼的,就是每个团队自己定义一套日志格式,解析起来简直要命。建议用 JSON 格式,字段标准化。
3.1.2 系统日志
系统日志很多人会忽略。但说实话,很多故障的根因其实不在应用层,而在系统层。
举个例子。有一次线上服务突然大面积超时,应用日志里全是数据库连接超时。大家一开始都在查 SQL、查连接池。结果我翻了翻系统日志,发现是磁盘 I/O 被打满了——有个定时任务在跑全量数据导出。
系统日志主要看这几个:
- /var/log/messages 或 syslog:系统级错误、OOM、磁盘告警
- dmesg:内核日志,特别是硬件相关的问题
- secure 或 auth.log:认证相关,有时候是被人扫了
3.1.3 中间件日志
中间件日志是连接应用和系统的桥梁。MySQL、Redis、Nginx、Kafka……每个中间件都有自己的日志体系。
我个人习惯在故障发生时,优先看中间件的慢查询日志和错误日志。比如:
- MySQL slow log:是不是有慢 SQL 把连接池打满了?
- Redis 的 latency 日志:是不是有大 key 操作导致阻塞?
- Nginx access log:请求量、响应码、响应时间,这些数据能帮你快速定位是入口问题还是后端问题。
小技巧:中间件日志通常量很大,别一股脑全拉下来。先根据时间窗口过滤,再根据错误级别筛选。我一般会用 grep + awk 先做一轮快速过滤。
3.2 监控数据收集:指标、链路、事件
日志是「点」,监控是「面」。单看日志容易一叶障目,结合监控才能看到全貌。
3.2.1 指标(Metrics)
指标是量化的数据。CPU、内存、磁盘、网络、QPS、延迟、错误率……这些是基础。但我想说的是,别只看平均值。
为什么?因为平均值会骗人。我曾经排查过一个案例,平均延迟只有 50ms,看起来很正常。但实际上一看 P99 延迟,已经飙到 5 秒了。那 99% 的用户体验极差,但平均值把问题掩盖了。
所以,我建议你关注这几个维度:
- P50、P90、P99、P999:分位延迟比平均值靠谱得多
- 错误率:5xx、4xx 的比例变化
- 饱和度:连接数、线程数、队列长度,这些指标往往能提前预警
3.2.2 链路(Tracing)
链路追踪是分布式系统的「X光机」。它能告诉你一个请求到底经过了哪些服务、每个服务花了多少时间。
我遇到过最典型的场景:一个接口突然变慢,日志里看不出问题,指标也正常。但一开链路追踪,发现是某个下游服务的某个接口响应时间从 10ms 变成了 3 秒。顺着链路一查,原来是那个服务依赖的 Redis 集群出了故障。
链路数据的关键字段:
- Trace ID:串联整个请求的唯一标识
- Span 耗时:每个环节的耗时分布
- 错误标记:哪个环节抛了异常
3.2.3 事件(Events)
事件是「发生了什么」。比如:发布、配置变更、扩缩容、告警触发、机房切换……
这些事件往往是故障的导火索。我个人的习惯是,在故障时间窗口内,把所有的变更事件拉出来,按时间线排列。很多时候,故障的根因就藏在这些事件里。
注意:事件数据一定要有自动化的采集机制。别靠人工记录,人记不住,也记不准。我曾经吃过这个亏——运维说「没改过配置」,结果一查审计日志,半小时前刚有人改了负载均衡策略。
3.3 上下文信息收集:变更记录、代码版本、配置
日志和监控告诉你「出了什么问题」,上下文信息告诉你「为什么会出现这个问题」。
3.3.1 变更记录
变更记录是根因分析里最重要的上下文。没有之一。
我统计过自己经手的故障,大概 70% 以上都和变更有关。发布新代码、修改配置、升级中间件、调整网络策略……每一次变更都是一次风险注入。
收集变更记录时,重点关注:
- 变更时间:和故障发生时间是否吻合?
- 变更内容:改了什么?为什么改?
- 变更人:方便后续回溯沟通
- 变更审批记录:有没有经过 review?
3.3.2 代码版本
代码版本信息能帮你快速定位「是不是这次发布引入的问题」。
我建议你在故障发生时,第一时间确认:
- 当前运行的代码版本:Git commit ID、tag 或 release 版本号
- 上一个稳定版本:对比两个版本的 diff
- 最近几次提交记录:特别是和故障模块相关的提交
嗯,这里要注意一点:有时候代码版本是对的,但构建出来的二进制包有问题。所以最好能保留每次构建的产物和构建日志。
3.3.3 配置
配置是故障的隐形杀手。代码没变,配置一变,系统可能就崩了。
我遇到过最离谱的一次:一个配置项从「true」改成了「True」,大小写不一样,结果整个配置解析失败,服务直接起不来。排查了整整两个小时才发现。
配置信息收集要点:
- 配置中心版本:配置有没有被修改?谁改的?什么时候改的?
- 配置生效范围:是全量生效还是灰度?
- 配置依赖关系:这个配置会影响哪些模块?
总结一下:故障信息收集不是简单的「把数据拉出来」,而是要有目的、有结构地去采集。日志看细节,监控看趋势,上下文看原因。三者缺一不可。
我曾经在一次大故障复盘时,发现团队花了 4 个小时在排查,但前 2 个小时都在「找数据」。从那以后,我推动团队做了故障信息自动采集的脚本,把日志、监控、变更记录一键打包。效果立竿见影——平均故障定位时间缩短了 60%。
说白了,信息收集这件事,功夫在平时。别等故障来了才想着怎么捞数据。提前把采集方案、工具链、流程都准备好,故障来了你才能从容应对。