一、概述

1.1 背景介绍

告警系统的失败往往不是"没告警",而是"告警太多"。当误报与无效告警占据值班注意力时,团队会产生典型的告警疲劳:真正的事故告警被淹没,响应变慢,MTTR 上升,最后变成"告警系统自己成为事故源"。

Prometheus + Alertmanager 是事实标准,但在很多组织里,告警规则长期处于以下状态:

  • 规则来源于个人经验,缺少 SLO/业务语义,无法解释"为什么这条告警重要"
  • 规则过度依赖正则与复杂标签匹配,维护困难、性能差、变更风险高
  • 缺少测试与回放,规则变更靠"上线观察",造成误报/漏报

LLM 的价值不在于"自动写 PromQL",而在于它能把"散落的经验"结构化:将规则与上下文(服务拓扑、SLO、历史事故、仪表盘、日志模式)一起输入,输出更符合 SRE 思维的告警设计,并给出可执行的验证与回滚路径。

1.2 技术特点

特点一:SLO 驱动而非阈值驱动

从"CPU > 80% 就告警"转向"错误预算消耗过快就告警",减少噪声并更贴近用户体验。

特点二:规则可测试(Rule-as-Code + 回放评估)

promtool test rules 或历史数据回放,在上线前量化评估误报/漏报风险。

特点三:LLM 辅助"重构与解释"

让模型做:规则解读、反模式识别、重构建议、参数解释、生成测试用例草案;最终上线仍以数据与门禁为准。

1.3 适用场景

  • 场景一:告警疲劳治理(降噪、分级、抑制、聚合、路由)
  • 场景二:SLO/错误预算体系落地(多窗口燃尽率告警)
  • 场景三:PromQL 规则重构与性能优化(降低计算开销与标签基数风险)

1.4 环境要求

组件版本要求说明
Prometheus2.4x+支持现代规则与查询能力
Alertmanager0.2x+路由、抑制、静默与分组能力
promtool与 Prometheus 同版本用于规则校验与测试
CI 执行环境Linux/容器用于在合并前跑规则校验与测试
LLM 服务内部或外部仅作为"规则重构助手",不可直接自动上线

二、详细步骤

2.1 准备工作

2.1.1 系统检查

promtool --version
curl -fsS http://<prometheus-host>:9090/-/healthy
curl -fsS http://<alertmanager-host>:9093/-/healthy

2.1.2 安装依赖

# 获取 promtool(通常随 Prometheus 发布包提供)
promtool --help

# 可选:用于回放/分析的工具
sudo apt update && sudo apt install -y jq ripgrep

2.2 核心配置

2.2.1 盘点现状:把"告警噪声"量化出来

先定义你要优化的指标,否则"误报率降了多少"无法度量。建议至少统计:

  • 告警总量、告警去重后事件量(按 fingerprint 聚合)
  • 页面告警(page)与通知告警(ticket/info)的比例
  • 告警关联真实事故的比例(需要和工单/复盘对齐)
  • Top N 噪声告警(占比、触发时间段、常见触发原因)
# 示例:从 Alertmanager API 拉取当前活跃告警(按需替换地址)
curl -fsS http://<alertmanager-host>:9093/api/v2/alerts | jq '.[].labels.alertname' | sort | uniq -c | sort -nr | head
说明:量化阶段往往会发现:一小部分规则贡献了大部分噪声。优先处理 Top 噪声告警,比"全面重写"更具性价比。

2.2.2 规则重构策略:从"阈值堆砌"到"SLO 告警"

把规则分成 3 类,并采用不同策略:

规则类型策略
用户体验类(优先 SLO)错误率、延迟分位、可用性,建议用错误预算燃尽率(多窗口)
容量与资源类CPU/内存/磁盘/连接数,建议用"趋势 + 余量"而不是单点阈值
组件健康类实例存活、关键依赖不可达,建议精简直接,避免过度计算

多窗口燃尽率告警示例(需要结合 SLO 目标与错误预算定义调整):

# 文件路径:rules/slo.yml(示例)
groups:
  - name: slo-burnrate
    rules:
      - alert: ApiErrorBudgetBurningFast
        expr: |
          (
            sum(rate(http_requests_total{job="api",status=~"5.."}[5m]))
            /
            sum(rate(http_requests_total{job="api"}[5m]))
          ) > 0.02
          and
          (
            sum(rate(http_requests_total{job="api",status=~"5.."}[1h]))
            /
            sum(rate(http_requests_total{job="api"}[1h]))
          ) > 0.01
        for: 2m
        labels:
          severity: page
          team: sre
        annotations:
          summary: "API 错误预算消耗过快"
          runbook: "<你的 Runbook 地址>"
说明:这类告警的目标是减少噪声:短窗口捕捉突发,长窗口防止短抖动误报。阈值必须以 SLO/错误预算为依据,而不是"经验值"。

2.2.3 用 LLM 辅助重构:提示词与门禁

LLM 参与告警重构建议采用"输入充分上下文 + 输出可验证产物"的模式:

输入建议包含

  • 现有规则(PromQL、for、labels、annotations)
  • 业务 SLO/SLI 定义(如果没有,就输出"缺失项清单")
  • 历史告警样本(触发时段、对应指标走势)
  • 复盘结论(哪些告警是有效信号,哪些是噪声)

输出必须包含

  • 重构后的规则
  • 变更理由(对应反模式)
  • 可执行验证方案(如何回放、如何灰度、如何回滚)

提示词示例

你是资深 SRE。以下是一个 Prometheus 告警规则与其历史触发情况。
请输出:
1) 该规则是否属于告警反模式(说明原因)
2) 重构后的规则(PromQL + for + labels/annotations)
3) 验证方案(promtool 测试、灰度策略、回滚条件)

约束:不要引入无法在 Prometheus 中实现的语法;不要使用不可控的正则;
如果缺少 SLO,请先给出 SLO 建议与缺失项。

2.3 启动和验证

2.3.1 上线前验证(强制)

# 规则语法校验
promtool check rules rules/*.yml

2.3.2 规则单测(推荐)

# 文件路径:rules/tests/slo_test.yml(示例:promtool test rules)
rule_files:
  - ../slo.yml

evaluation_interval: 1m

tests:
  - interval: 1m
    input_series:
      - series: 'http_requests_total{job="api",status="500"}'
        values: '0+10x120'
      - series: 'http_requests_total{job="api",status="200"}'
        values: '0+990x120'
    alert_rule_test:
      - eval_time: 10m
        alertname: ApiErrorBudgetBurningFast
        exp_alerts:
          - exp_labels:
              severity: page
              team: sre
promtool test rules rules/tests/slo_test.yml

预期输出

  • 规则语法通过
  • 测试用例在预期时间点触发(或不触发)
  • 输出可作为"规则变更门禁"的一部分

三、示例代码和配置

3.1 完整配置示例

3.1.1 主配置文件

# 文件路径:rules/alerts.yml(示例)
groups:
  - name: infra
    rules:
      - alert: NodeDiskWillFillIn24Hours
        expr: |
          predict_linear(node_filesystem_free_bytes{fstype!~"tmpfs|overlay"}[6h], 24*3600) < 0
        for: 30m
        labels:
          severity: ticket
        annotations:
          summary: "磁盘空间预计 24 小时内耗尽"
          description: "请检查增长最快的目录与日志轮转策略"

3.1.2 辅助脚本

#!/bin/bash
# 文件名:tools/check_rules.sh
set -euo pipefail

promtool check rules rules/*.yml
promtool test rules rules/tests/*.yml
echo "rules_ok"

3.2 实际应用案例

案例一:把"CPU > 80%"改成"容量风险"告警

场景描述:CPU 高并不一定是事故。更有效的是预测"余量将耗尽",并把告警路由为 ticket(可计划处理),而不是 page。

实现步骤

  1. 用趋势指标(如 predict_linear)替代单点阈值
  2. 为告警补齐 runbook(如何定位占用、如何扩容、如何降级)
  3. 按严重性分级路由与静默策略(值班不被噪声打爆)

案例二:把"正则堆砌"的错误率告警改为 SLO 燃尽率

场景描述:正则匹配易错且维护成本高。将错误率定义与 SLO/SLI 绑定,配合多窗口燃尽率策略,通常能显著减少误报并提升可解释性。

实现步骤

  1. 明确 SLI(请求总量、错误请求)与统计口径
  2. 设计燃尽率阈值与窗口(短 + 长)
  3. 上线前回放历史事故与噪声区间,验证触发行为

四、最佳实践和注意事项

4.1 最佳实践

4.1.1 性能优化

优化点一:控制标签基数,避免规则计算炸裂

在规则中对高基数标签做 sum by(...) 聚合,避免每个实例/用户维度都触发告警。

# 查看 Prometheus 规则评估耗时相关指标
curl -fsS http://<prometheus-host>:9090/metrics | rg "prometheus_rule_evaluation_duration_seconds"

优化点二:减少正则,优先使用明确标签

正则会提高维护成本与查询开销。标签治理比规则技巧更重要。

优化点三:建立"规则变更门禁"

规则变更必须包含:语法校验、单测、灰度、回滚条件、告警路由评审。

4.1.2 安全加固

安全措施一:变更可追溯与审批

告警规则属于"生产控制面"配置,必须有审批与回滚机制。

安全措施二:告警渠道最小化

page 只发真正影响用户体验的信号;其余进入 ticket 或日报,减少无效中断。

4.1.3 高可用配置

  • HA 方案一:双 Alertmanager + 去重,避免单点导致告警丢失或风暴
  • HA 方案二:分环境规则(生产/预发/测试隔离),防止测试噪声污染值班
  • 备份策略:规则、路由、抑制与静默策略都需要可回滚版本

4.2 注意事项

4.2.1 配置注意事项

警告:不要让 LLM 直接"生成规则并自动上线"。它最多是建议者,最终必须用数据回放与门禁来决定是否进入生产。
  • 注意事项一:SLO/SLI 不清晰时,先补齐定义,再谈告警规则
  • 注意事项二:任何"减少误报"的改动都可能引入漏报,必须评估二者平衡
  • 注意事项三:路由与抑制规则需要同步调整,否则规则再好也会变噪声

4.2.2 常见错误

错误现象原因分析解决方案
告警风暴缺少分组/抑制/for 太短调整 Alertmanager group;合理设置for;加抑制规则
告警漏报聚合过度或阈值过高回放历史事故;分级告警;加入短窗口信号
查询太慢高基数 + 正则 + 长窗口先聚合再计算;减少正则;用 recording rules

4.2.3 兼容性问题

  • 版本兼容:Prometheus/Alertmanager 版本差异会影响字段与行为,升级需灰度
  • 平台兼容:K8s/VM 指标名称与标签差异较大,需要统一采集规范
  • 组件依赖:规则依赖的指标一旦重命名/下线,告警会静默失效,需做指标契约管理

五、故障排查和监控

5.1 故障排查

5.1.1 日志查看

# Prometheus 自身日志(路径按部署方式调整)
kubectl -n monitoring logs deploy/prometheus | tail -200

# Alertmanager 日志
kubectl -n monitoring logs deploy/alertmanager | tail -200

5.1.2 常见问题排查

问题一:规则不触发

# 直接在 Prometheus Web UI 或 API 查询 expr 对应的 PromQL 是否有数据
curl -G -fsS "http://<prometheus-host>:9090/api/v1/query" --data-urlencode 'query=up'

解决方案:排查指标是否存在、标签是否匹配、采集是否断流;必要时为关键指标建立 recording rules 并做契约校验。

5.2 性能监控

5.2.1 关键指标监控

# 建议关注 Prometheus 规则评估耗时与失败率相关指标
curl -fsS http://<prometheus-host>:9090/metrics | rg "prometheus_rule_evaluation"

5.2.2 监控指标说明

指标名称正常范围告警阈值说明
规则评估耗时稳定持续升高可能是标签基数或查询复杂度问题
规则评估失败接近 0> 0表示规则语法或依赖指标异常
告警事件量稳定突增需要识别告警风暴与噪声来源

5.2.3 监控告警配置

groups:
  - name: prometheus-self
    rules:
      - alert: PrometheusRuleEvaluationSlow
        expr: histogram_quantile(0.99, sum(rate(prometheus_rule_evaluation_duration_seconds_bucket[5m])) by (le)) > 1
        for: 10m
        labels:
          severity: ticket
        annotations:
          summary: "Prometheus 规则评估变慢"

5.3 备份与恢复

5.3.1 备份策略

#!/bin/bash
# 备份脚本示例:规则与路由配置
set -euo pipefail
ts="$(date +%Y%m%d-%H%M%S)"
tar -czf "/backup/prom-rules-$ts.tgz" rules/ alertmanager/
echo "backup_ok=$ts"

5.3.2 恢复流程

  1. 回滚规则文件:恢复到上一个稳定版本
  2. 校验与加载:promtool check rules 后再 reload
  3. 观察指标:确认规则评估耗时与告警量恢复正常

六、总结

6.1 技术要点回顾

  • 要点一:告警治理先量化,再优化;优先处理 Top 噪声告警
  • 要点二:SLO 驱动告警比阈值堆砌更贴近用户体验,也更抗抖动
  • 要点三:LLM 可用于重构与解释,但上线必须走"校验+测试+灰度+回滚"门禁
  • 要点四:告警系统的可靠性来自"规则 + 路由 + 抑制 + 人的流程"共同作用

6.2 进阶学习方向

方向一:SLO/错误预算体系

  • 学习资源:SRE 相关经典实践(SLO/SLI/Error Budget)
  • 实践建议:先选 1~2 条关键用户旅程落地 SLO,再扩展到全服务

方向二:规则测试与回放平台

  • 学习资源:promtool 测试、历史数据回放
  • 实践建议:把规则测试纳入 CI 门禁,降低变更风险

方向三:告警降噪工程

  • 学习资源:Alertmanager 分组/抑制/静默、事件聚合
  • 实践建议:从"Page 只留用户体验信号"开始治理

6.3 参考资料


附录

A. 命令速查表

# 规则语法校验
promtool check rules rules/*.yml

# 规则单测执行
promtool test rules rules/tests/*.yml

# 查看当前活跃告警
curl -fsS http://<alertmanager-host>:9093/api/v2/alerts | jq '.[].labels.alertname'

B. 配置参数详解

参数说明
for抖动过滤器,不是"延迟告警",而是减少误报的重要手段
severity告警分级的基础字段,必须与路由策略一致
annotations.runbook让告警可执行,减少值班人员的上下文切换成本

C. 术语表

术语英文解释
服务等级目标SLO用户体验底线,用于约束告警与变更节奏
错误预算Error Budget可用性目标允许的失败额度,燃尽率告警以此为依据
告警疲劳Alert Fatigue告警过载导致团队对告警不再敏感,响应变慢
正文到此结束
  • 本文作者:xinyu.he
  • 文章标题:告别写正则:用大模型重构 Prometheus 告警规则,降低误报的工程方法
  • 本文地址:https://www.hxy.bj.cn/archives/815/
  • 版权说明:若无注明,本文皆Xinyu.he blog原创,转载请保留文章出处。
最后修改:2026 年 05 月 12 日
如果觉得我的文章对你有用,请随意赞赏