3. 告警规则编写:Prometheus告警规则语法、告警表达式、标签与注解
告警规则是 Prometheus 监控体系的核心“触发器”。一条精准的告警规则,能够在系统出现异常时第一时间通知 SRE 团队,并携带足够的上下文信息用于快速定位。本章将深入剖析告警规则的语法结构、表达式编写技巧以及标签与注解的最佳实践。
3.1 告警规则文件结构与语法
Prometheus 告警规则采用 YAML 格式定义,通常保存在独立的规则文件中(如 alerts.yml),并在 Prometheus 主配置中通过 rule_files 字段加载。
核心语法结构:
groups:
- name: <group_name> # 规则组名称,必须唯一
interval: <duration> # 规则评估间隔(可选,默认继承全局配置)
rules:
- alert: <alert_name> # 告警名称,必须唯一
expr: <promql_expression> # PromQL 表达式,触发条件
for: <duration> # 持续时间,满足条件持续多久才触发
labels: # 附加标签(可选)
<key>: <value>
annotations: # 注解(可选),用于传递上下文信息
<key>: <value>
| 字段 | 必填 | 说明 | 示例 |
|---|---|---|---|
groups[].name |
是 | 规则组名称,用于逻辑分组 | node_alerts |
groups[].interval |
否 | 该组规则的评估频率 | 30s |
rules[].alert |
是 | 告警名称,在告警通知中作为标题 | HighCPUUsage |
rules[].expr |
是 | PromQL 表达式,返回非零值即触发 | node_cpu_seconds_total > 0.9 |
rules[].for |
否 | 表达式持续满足该时长后才触发告警,用于防止抖动 | 5m |
rules[].labels |
否 | 附加标签,会覆盖原始指标标签,常用于路由告警 | severity: critical |
rules[].annotations |
否 | 注解,用于携带描述、链接、Runbook 等上下文 | summary: "CPU usage is high" |
最佳实践:规则组名称应反映其监控对象(如
kubernetes_nodes、database_instances),便于管理和排错。评估间隔建议与数据采集间隔保持一致或为其整数倍。
3.2 告警表达式编写核心原则
告警表达式是 PromQL 查询语句,其返回值决定了告警是否触发。编写高质量表达式需要遵循以下原则:
- 返回非零值即触发:Prometheus 将表达式结果中所有非零(且非 NaN)的样本视为触发状态。因此,常用比较运算符(
>、<、==)生成 0 或 1 的结果。 - 避免空结果:如果表达式返回空向量,则不会触发告警。对于“无数据”场景,应使用
absent()函数。 - 使用
for消除抖动:设置合理的持续时间,避免瞬时峰值导致误告警。 - 聚合与分组:使用
by或without子句控制告警的粒度,避免为每个实例生成过多告警。
常见表达式模式:
# 1. 阈值比较(CPU 使用率 > 80%)
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
# 2. 速率异常(5分钟内错误率超过 5%)
sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) > 0.05
# 3. 无数据检测(实例离线)
absent(node_cpu_seconds_total{instance="192.168.1.1:9100"}) == 1
# 4. 预测趋势(磁盘 6 小时内会满)
predict_linear(node_filesystem_free_bytes{mountpoint="/"}[6h], 6 * 3600) < 0
3.3 标签与注解:告警的“元数据”
标签(labels)和注解(annotations)是告警规则中传递上下文的关键字段,直接影响告警的路由、去重和可读性。
3.3.1 标签(Labels)
标签用于标识告警的属性和路由策略。Prometheus 会将原始指标标签与规则中定义的标签合并,形成告警的唯一标识。常用标签包括:
severity:严重级别(critical、warning、info),用于告警分级。team:负责团队,用于路由到正确的通知渠道。env:环境标识(prod、staging),便于区分。
3.3.2 注解(Annotations)
注解用于提供人类可读的描述和操作指引,不会影响告警的路由。推荐包含以下信息:
summary:简短摘要,概括告警内容。description:详细描述,包含当前值、阈值、实例等动态信息。runbook_url:指向 Runbook 文档的链接,便于快速响应。dashboard_url:指向相关监控面板的链接。
完整告警规则示例:
groups:
- name: node_alerts
interval: 30s
rules:
- alert: HighCPUUsage
expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 90
for: 5m
labels:
severity: critical
team: platform
annotations:
summary: "Instance {{ $labels.instance }} CPU usage is high"
description: "CPU usage has been above 90% for more than 5 minutes. Current value: {{ $value }}%"
runbook_url: "https://runbook.example.com/high-cpu-usage"
dashboard_url: "https://grafana.example.com/d/node-cpu"
3.4 告警规则生命周期与状态机
理解告警的状态转换有助于排查告警未触发或重复告警的问题。下图展示了告警从评估到恢复的完整流程:
3.5 告警规则编写避坑指南
常见陷阱与解决方案:
- 陷阱:表达式返回多个时间序列,导致告警爆炸。
解决:使用by子句聚合,或设置alert_relabel_configs进行标签降维。 - 陷阱:
for时间设置过短,频繁误告警。
解决:根据指标波动特性设置for,通常建议 3-5 分钟。 - 陷阱:注解中未使用模板变量,告警信息千篇一律。
解决:使用{{ $labels.xxx }}和{{ $value }}动态填充实例名称和当前值。 - 陷阱:规则文件语法错误导致 Prometheus 无法加载。
解决:使用promtool check rules命令进行本地校验。
3.6 告警规则与 CI/CD 联动设计
在自动化运维体系中,告警规则不应是静态的。通过 CI/CD 管道管理规则文件,可以实现版本控制、自动化测试和灰度发布。下图展示了告警规则在 CI/CD 中的流转过程:
CI/CD 集成要点:
- 在 CI 阶段执行
promtool check rules alerts.yml进行语法校验。 - 使用
promtool test rules test.yml进行单元测试,验证表达式在给定输入下的输出。 - 通过配置管理工具(如 Ansible、Helm)将规则文件分发到 Prometheus 服务器,并触发热加载(
POST /-/reload)。 - 在测试环境中使用模拟指标数据验证告警触发与恢复逻辑。