告警发出来之后,谁来查根因?

告警只能告诉你「坏了」,根因排查才是值班耗时的大头。本文拆解告警与排障之间的真空区,并介绍开源项目 catpaw:插件发现异常、事件引擎做去重与告警控制、告警触发后 AI 自动调用 70+ 诊断工具做根因初筛,把结构化报告与告警一起送达值班链路。

作者 秦晓辉

TL;DR:大多数监控系统只负责告诉你"坏了",但真正耗时的是后面的根因排查。catpaw 想补上的不是又一套 dashboard,而是另一段链路:插件发现异常,事件引擎做去重和告警控制,AI 在告警触发后自动调用 70+ 诊断工具做第一轮根因分析,再把结构化报告跟告警一起送到你的值班链路里。

catpaw 新鲜开源,项目地址:https://github.com/cprobe/catpaw 欢迎关注收藏。

如果想加入微信交流群,可以加我好友:picobyte,我拉你进群。不过大概率是不需要的,因为 AI 时代了,让 AI 探索一下代码,可以回答任何你想问的问题。

核心要点摘要

  • 传统告警通常只完成异常发现,真正耗时的是告警之后的上下文收集和根因初筛。
  • 一个可用的告警闭环至少需要异常发现、标准化事件、噪声控制、诊断动作选择、结构化报告和回到值班链路六个环节。
  • catpaw 的价值不是再做一个 dashboard,而是在告警触发后调用诊断工具,把证据、上下文和第一轮判断一起送到通知渠道。
  • AI 诊断要基于工具和证据,而不是只根据告警文本生成看似合理的解释。
  • 这类系统应先做只读诊断和根因初筛,自动修复必须有确认、权限和边界控制。

这篇文章适合谁读

  • 已经有监控告警,但值班人收到告警后仍要手工补大量上下文的团队。
  • 想把 Linux、网络、进程、fd、conntrack、systemd 等基础设施问题诊断流程标准化的 SRE。
  • 正在评估 AI 运维工具,但不希望模型只根据告警文本“自由发挥”的工程团队。
  • 希望把告警、诊断证据和通知渠道打通,而不是让排障结论散落在 SSH 终端里的团队。

凌晨 3 点,你收到一条再普通不过的告警

手机亮了。

[Critical] disk::space_usage target=/ disk usage 97.2% >= critical threshold 95.0%

这条告警当然有用。至少你知道根分区快满了。

但它只解决了值班流程里最容易的一步:发现有问题。

真正耗时的部分是后面这些:

  • 是哪个目录涨起来了?
  • 是日志没轮转,还是 core dump 堆积?
  • inode 也快满了吗?
  • 这是一次性峰值,还是会持续恶化?
  • 我现在该先删文件、先扩容,还是先止血?

于是你开始 SSH 上机:

df -h
df -i
du -sh /* 2>/dev/null | sort -rh | head
du -sh /var/* 2>/dev/null | sort -rh | head
lsof +L1 | head

如果这是磁盘问题,还算有路径。

如果告警换成 conntrack usage 92%ListenOverflows 持续增长、CLOSE_WAIT 破千,排查链路会更长,命令也更散。更麻烦的是,很多时候值班的人并不是最熟 Linux 内核细节的那位。

大多数告警系统做到这里就停了。

它们负责把异常抛给你,却不负责把这条异常往根因推进一步。

一条告警,通常只完成了故障处理的前 20%

为什么值班体验常常很差?

不是因为没有告警。

而是因为告警和排障之间有一段没人接住的真空区。

可以把故障处理粗暴分成三层:

层次 你想知道什么 传统系统通常做到哪里
异常发现 出问题了吗 做得不错
上下文收集 出了什么问题,范围多大 常常不足
根因初筛 最可能为什么出问题,下一步先查什么 基本靠人肉

也就是说,很多系统其实只回答了:

“是的,坏了。”

但值班时真正需要的是:

“为什么坏?先查哪里?有没有明显的高概率根因?”

这不是吹毛求疵,而是 On-call 成本的核心。

一条没有上下文的告警,意味着:

  • 值班人要自己补充上下文
  • 经验不足的人会走很多弯路
  • 交接时只能靠口头描述
  • 告警越多,人越麻木

所以更合理的问题不是"要不要告警",而是:

告警发出来之后,系统能不能顺手完成第一轮排查?

一个真正可用的告警闭环,至少要有 6 个环节

如果你想让监控系统不只会"报错",而是能把人从机械排查里解放一点,它至少要补齐下面这条链路:

环节 作用 缺失时的后果
发现异常 稳定识别磁盘、网络、进程、系统服务等异常信号 故障只能靠用户反馈或人工巡检发现
标准化事件 统一 check、target、当前值、阈值和严重级别 后续无法做去重、聚合和诊断编排
噪声控制 去重、抑制、聚合和重复通知控制 告警风暴会把人和模型一起淹没
自动选择诊断动作 根据异常类型调用合适工具 AI 容易停留在猜测和泛化建议
结构化报告 输出概要、根因、证据和建议动作 值班人仍要从原始命令里人工整理结论
回到值班链路 把诊断结果送到同一通知渠道 告警和诊断割裂,交接困难

1. 先发现异常

这一步是传统监控的强项。

比如磁盘使用率超过阈值、conntrack 表快满、NTP 漂移过大、systemd 服务挂掉,先把这些异常稳定地发现出来。

2. 把异常变成标准化事件

如果每个插件、每个脚本、每个团队都输出自己的格式,后面根本无法做统一处理。

事件里至少要有:

  • check 是什么
  • target 是谁
  • 当前值是多少
  • 阈值是什么
  • 严重级别是什么

3. 做掉那些会把人淹死的噪音

没有去重、抑制、聚合,AI 诊断也没法做。

因为同一个目标在几秒内可能连续打出多条关联告警:

  • 磁盘空间高
  • inode 高
  • writable 失败
  • 日志关键字异常

如果每条都单独跑一遍重诊断,只会放大噪声和成本。

4. 根据异常上下文自动选择诊断动作

磁盘告警该看目录占用、inode、日志、deleted-but-open file。

conntrack 告警该看当前计数、上限、丢包证据、相关内核参数。

ListenOverflow 告警该看 backlog、队列溢出计数、socket 分布、TCP 调优项。

这一步如果没有工具体系,AI 很容易沦为"会说话的猜测器"。

5. 产出结构化报告

不是一堆原始命令输出,而是能直接被人拿去决策的结果:

  • 问题概要
  • 高概率根因
  • 关键证据
  • 建议动作

6. 报告要回到值班链路里

如果诊断结论只躺在某个本地终端里,还是没有意义。

真正有用的方式是:告警发出去之后,诊断报告也作为新事件进入同一条通知链路。

这样值班人打开手机,不只看到"坏了",还能看到"大概率为什么坏了"。

catpaw 补的,就是这段从告警到根因之间的链路

catpaw 的定位从一开始就不是指标采集器,而是一个轻量的 check 型 Agent,加上一段 AI 驱动的诊断闭环。

如果把链路画简单一点,大概是这样:

插件检查 -> 标准化事件 -> 告警判定/去重/重复控制
                        -> 发送通知
                        -> 触发 AI 诊断
                        -> 调用内置诊断工具
                        -> 生成结构化报告
                        -> 报告再次发送到通知渠道

这条链路里有几个点是比较关键的。

1. 检查插件负责"发现异常"

catpaw 现在已经有 25+ 个检查插件,覆盖的不是一堆泛泛的 metrics,而是更贴近故障的风险点:

  • disk:空间、inode、可写性
  • conntrack:连接跟踪表使用率
  • tcpstate:CLOSE_WAIT / TIME_WAIT
  • sockstat:listen 队列溢出
  • sysctl:关键内核参数漂移
  • procfd / filefd:进程级和系统级 fd 耗尽
  • systemd:服务状态
  • redis:单机、主从、集群 Redis 的关键健康项

这和"先把所有指标采上来,回头再想怎么告警"是两种思路。

它更接近 SRE 真正在值班中关心的问题:有没有已经构成故障的信号。

2. 事件引擎负责"别把人和模型一起吵死"

告警不是直接裸发的。

catpaw 的事件引擎会先做一轮事件处理,包括:

  • 标准化字段
  • 计算 AlertKey
  • for_duration 持续确认
  • repeat_interval / repeat_number 控制重复通知
  • 恢复通知

这一步的价值很实际:

  • 避免抖动告警频繁触发
  • 避免同一个问题一分钟提醒十次
  • 给后面的诊断环节一个相对稳定的触发点

3. 诊断前先做聚合,不是每条告警都单独查

catpaw 在告警真正送出后,才会判断是否触发 AI 诊断。

而且不是每来一条就立刻查一次,而是会把同一目标的多个关联告警放进一个短窗口里聚合,再统一提交给诊断引擎。

这非常重要。

因为真实故障往往不是单点症状:

  • 某个盘满了,同时 inode 也高
  • 某个服务连接泄漏,同时 CLOSE_WAIT 和 fd 使用率一起涨
  • 某个节点网络出问题,同时 ping、TCP、日志关键字一起异常

聚合之后再诊断,模型拿到的是一组更接近真实故障面的上下文,而不是一条孤零零的告警。

4. AI 不是胡猜,而是调工具

这是 catpaw 和很多"AI 告警摘要"类产品最大的差别。

它不是把一条告警文本扔给模型,让模型凭空写一段漂亮但没证据的话。

它背后有一套 70+ 的诊断工具箱,覆盖:

  • CPU / 内存 / OOM / PSI
  • 磁盘空间 / I/O / block device / LVM
  • DNS / ping / traceroute / TCP 状态 / 重传
  • 进程线程 / open files / environment / cgroup
  • dmesg / journald / 日志 grep
  • conntrack / firewall / sysctl / SELinux / AppArmor
  • Docker / systemd

如果你接了 MCP,还可以继续查 Prometheus、Jaeger、CMDB 这类外部上下文。

所以它做的是:

告警触发 -> 带上下文调用工具 -> 基于证据生成第一轮诊断

而不是:

看到告警文本 -> 语言模型自由发挥

用一个磁盘场景看,“闭环"到底长什么样

还是看那个最常见的场景:根分区满了。

传统告警通常停在这里

[Critical] disk::space_usage target=/ disk usage 97.2% >= critical threshold 95.0%

它告诉你现象,但没告诉你原因。

如果靠人工,通常要做这些

df -h
df -i
du -sh /* 2>/dev/null | sort -rh | head
du -sh /var/* 2>/dev/null | sort -rh | head
lsof +L1 | head

然后你再从这些原始输出里人工提炼判断。

catpaw 更理想的结果应该是这样

告警发出去后,再跟一份结构化诊断报告:

## 诊断报告

### 问题概要
/ 分区使用率 97.2%,超过 Critical 阈值 95.0%。

### 高概率根因
- /var/log/app/access.log 占用 25.3GB,最近持续增长
- 目标路径未配置 logrotate
- /tmp 下存在多个 core dump,共计 8.2GB

### 关键证据
- 根分区总量 50GB,已用 47GB
- inode 使用率正常,不是小文件过多
- 未发现明显 deleted-but-open file

### 建议动作
1. 先清理 core dump 和无用日志,尽快止血
2. 为 /var/log/app/*.log 配置日志轮转
3. 如果业务量持续增长,考虑把日志迁移到独立分区

这份报告未必 100% 正确,但它已经把值班动作从:

“我要先想想该跑什么命令”

推进成了:

“我先验证这几个高概率点”

这对值班效率的提升非常实在。

再看一个更典型的 SRE 场景:conntrack 表快满

磁盘满的问题,大多数人多少还有经验。

conntrack 就不一样了。

很多团队线上出了问题,第一反应还是:

  • 服务是不是挂了
  • 网络是不是抖了
  • 对端是不是超时了

但 conntrack 满的时候,真实现象常常是:

  • 新连接静默失败
  • 客户端看到的是 timeout
  • 服务端进程一脸无辜
  • Grafana 四大金指标一片正常

如果告警只写:

[Critical] conntrack::usage target=host nf_conntrack usage 92% >= 90%

那接下来还是得靠值班人自己联想:

  • 当前条目数和上限分别是多少
  • 最近是不是已经出现过 dropped packet
  • 机器角色是不是 NAT 网关 / K8s 节点 / 高并发入口
  • 是不是应该立刻提 nf_conntrack_max

这就是为什么我觉得 SRE 更应该关心的,不是"AI 会不会写报告”,而是:

系统能不能把排障路径往前推一段。

对于 conntrack 这种问题,哪怕只帮你自动补出下面这些证据,价值都很高:

  • 当前 nf_conntrack_count / nf_conntrack_max
  • 是否接近硬上限
  • 是否出现 table full, dropping packet
  • 近期网络超时是否和该节点集中相关

对值班人来说,这已经不是"文案优化",而是实际减少误判。

这件事为什么以前难做

看起来像一句很自然的话:

“告警之后顺手查一下不就好了。”

但工程上真做起来并不简单。

1. 不是每条告警都值得深查

如果没有聚合、冷却、并发控制,系统很容易在告警风暴里把自己拖死。

catpaw 这里有几层保护:

  • 聚合窗口:把同一目标的关联告警合起来
  • cooldown:同一目标短时间内不要重复诊断
  • 并发上限:同时跑的诊断数量可控
  • 工具超时:避免单个工具卡死整个流程

2. 没有工具体系,AI 很容易幻觉

只给模型一条告警文本,生成出来的大概率只是"看起来合理"。

真正可靠的是:

  • 给它明确的工具目录
  • 给它具体的告警上下文
  • 限制它通过可复现的工具拿证据

3. 诊断动作必须安全

值班诊断不等于自动修复。

大部分诊断动作应该是只读的;如果真要执行 shell,也应该先征得确认。

否则系统很容易从"自动排障"滑向"自动闯祸"。

4. 结果必须回到同一条值班链路

如果告警在 PagerDuty,诊断报告在 SSH 终端,流程还是断的。

值班系统真正需要的是:

  • 一条原始告警
  • 一条可追溯的诊断报告
  • 两者都能进入同一通知渠道

只有这样,闭环才成立。

在 catpaw 里,最小化体验这件事并不复杂

如果你只是想感受一下"告警后自动诊断"是什么体验,最简单的方式就是用默认 console 通知加一个容易触发的插件先跑起来。

1. 先保留默认 console 输出

conf.d/config.toml 默认已经开了:

[notify.console]
enabled = true

这意味着你不需要先接 Flashduty、PagerDuty 或 WebAPI,就能在终端里看到事件。

2. 打开 AI 诊断

可以先按最小配置开启:

[ai]
enabled = true
model_priority = ["gpt4o"]
aggregate_window = "2s"

[ai.models.gpt4o]
base_url = "https://api.openai.com/v1"
api_key = "${OPENAI_API_KEY}"
model = "gpt-4o"

3. 选一个适合演示的插件

比如 disk 插件本身就很适合展示"从告警到根因":

[[instances]]
[instances.space_usage]
warn_ge = 90.0
critical_ge = 99.0

[instances.alerting]
for_duration = 0
repeat_interval = "5m"
repeat_number = 3

[instances.diagnose]
enabled = true

如果你更想展示 Linux 内核层问题,也可以直接用 conntrack

[[instances]]
[instances.conntrack_usage]
warn_ge = 75.0
critical_ge = 90.0

interval = "30s"

[instances.alerting]
for_duration = 0
repeat_interval = "5m"
repeat_number = 0

4. 先在测试机上故意制造一个容易触发的场景

比如:

  • 把某个阈值临时调低
  • 或在测试环境制造少量磁盘占用

然后启动:

./catpaw run

你看到的就不应该只是一条原始异常,而应该是:

  1. 原始告警事件
  2. 稍后跟上的诊断报告事件

如果你愿意进一步验证工具层的可靠性,还可以直接跑:

./catpaw selftest

这会对本地诊断工具做一轮冒烟测试。

真正值得推广的,不是"AI"三个字,而是值班成本下降

我觉得 catpaw 如果要打动 SRE / DEV,重点不该是"我们用了 AI"。

因为 SRE 真正关心的从来不是模型名,而是这些更朴素的问题:

  • 这东西能不能少让我 SSH 几次
  • 能不能帮经验不足的人少走弯路
  • 能不能把值班信息交接得更完整
  • 能不能减少那种"知道坏了,但不知道先查哪"的空转时间

如果一套系统只能告诉你"磁盘 97%"、“CLOSE_WAIT 2000”、“conntrack 92%",那它只是把问题转交给了人。

如果它还能把证据、上下文、第一轮根因判断一起发出来,它才开始真正参与故障处理。

告警不是终点。

对值班人来说,根因初筛才是真正开始产生价值的地方。

FAQ

catpaw 是替代 Prometheus、夜莺或其他监控系统吗?

不是。本文讨论的是告警之后的根因初筛链路。catpaw 更像轻量 check 型 Agent 和 AI 诊断闭环,重点是发现更贴近故障的风险点,并在告警触发后补充第一轮诊断证据。

AI 诊断报告能直接当最终根因吗?

不能。更合理的定位是“第一轮根因初筛”。它能把值班动作从“先想该跑什么命令”推进到“先验证哪些高概率点”,但最终处置仍需要工程师结合业务上下文判断。

为什么强调 AI 要调用工具?

只把告警文本交给模型,输出很容易变成看起来合理但缺少证据的猜测。调用只读诊断工具后,报告可以基于磁盘、网络、进程、日志、内核参数等现场证据生成,可靠性更高。

诊断动作会不会有风险?

诊断应该以只读为主。涉及 shell 执行、自动修复或有副作用的动作时,应先征得确认,并设置超时、并发上限和权限边界。本文重点讨论的是告警后的证据收集和根因初筛,不是无人值守自动修复。

最后给一份可以带走的 checklist

如果你想判断自己的监控体系是不是还停留在"只会报警"阶段,可以快速过一遍这几个问题:

  • 告警触发后,值班人是否还要手工补齐大部分上下文?
  • 同一故障是否会在几秒内打出多条互相有关但彼此割裂的告警?
  • 你的值班通知里,是否只有"现象"而几乎没有"证据”?
  • 遇到内核层、网络层、fd、队列、sysctl 这类问题时,是否仍严重依赖少数资深同学?
  • 你们的值班链路里,是否还缺少"异常发现之后的第一轮根因分析"?

如果这些问题里有几个答案是"是",那你缺的可能就不是更多 dashboard,而是这段从告警到根因之间的闭环。

延伸路径

继续看解决方案和产品对比

如果你正在做监控、可观测性或故障定位相关选型,建议从解决方案和产品对比继续往下看。

标签 监控告警
快猫星云 联系方式 快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云