乐于分享
好东西不私藏

告警发出来之后,自动查根因的神器来了

告警发出来之后,自动查根因的神器来了

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

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

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

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

手机亮了。

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

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

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

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

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

于是你开始 SSH 上机:

df -hdf -idu -sh /* 2>/dev/null | sort -rh | headdu -sh /var/* 2>/dev/null | sort -rh | headlsof +L1 | head

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

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

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

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

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

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

不是因为没有告警。

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

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

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

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

“是的,坏了。”

但值班时真正需要的是:

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

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

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

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

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

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

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

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

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:关键内核参数漂移
  • procfdfilefd:进程级和系统级 fd 耗尽
  • systemd:服务状态
  • redis:单机、主从、集群 Redis 的关键健康项

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

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

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

告警不是直接裸发的。

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

  • 标准化字段
  • 计算 AlertKey
  • for_duration持续确认
  • repeat_intervalrepeat_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 -hdf -idu -sh /* 2>/dev/null | sort -rh | headdu -sh /var/* 2>/dev/null | sort -rh | headlsof +L1 | head

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

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

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

## 诊断报告### 问题概要/ 分区使用率 97.2%,超过 Critical 阈值 95.0%。### 高概率根因/var/log/app/access.log 占用 25.3GB,最近持续增长目标路径未配置 logrotate/tmp 下存在多个 core dump,共计 8.2GB### 关键证据根分区总量 50GB,已用 47GBinode 使用率正常,不是小文件过多未发现明显 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 = truemodel_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.0critical_ge = 99.0[instances.alerting]for_duration = 0repeat_interval = "5m"repeat_number = 3[instances.diagnose]enabled = true

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

[[instances]][instances.conntrack_usage]warn_ge = 75.0critical_ge = 90.0interval = "30s"[instances.alerting]for_duration = 0repeat_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%”,那它只是把问题转交给了人。

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

告警不是终点。

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

最后给一份可以带走的 checklist

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

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

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

本站文章均为手工撰写未经允许谢绝转载:夜雨聆风 » 告警发出来之后,自动查根因的神器来了

猜你喜欢

  • 暂无文章