3. 告警规则基础:规则定义、表达式、条件、持续时间、标签与注释

告警规则是Grafana可观测性体系的“触发引擎”。一条规则定义了“何时、基于什么数据、持续多久、产生什么告警”。理解规则的每个组成部分,是后续进行参数化测试验证的前提。本章将拆解告警规则的六大核心要素,并建立它们之间的逻辑关系。

3.1 规则定义:从数据源到告警实例的映射

在Grafana中,一条告警规则本质上是一个评估任务。它定期从数据源(如Prometheus、Loki、CloudWatch)查询数据,将查询结果与预设条件进行比较,最终决定是否触发告警实例。

规则定义包含以下元数据字段:

字段 说明 示例值
规则名称 唯一标识,用于告警列表和通知中 HighCPUUsage-Prod
数据源 查询的目标数据源类型及实例 Prometheus-Prod-01
查询表达式 从数据源获取时序数据的语句 avg by(instance) (cpu_usage)
评估频率 规则被重新评估的时间间隔 30s
评估超时 单次查询允许的最大执行时间 60s
文件夹 规则的组织分类 Production/Infra
测试要点:在参数化测试中,评估频率和评估超时是常见的边界测试参数。例如,将评估频率设置为1s(低于推荐值)来验证系统在高频评估下的稳定性。

3.2 表达式:告警逻辑的核心

表达式是告警规则的“大脑”。它定义了从数据源中提取哪些数据,以及如何计算这些数据。Grafana支持多种表达式类型,最常用的是PromQL(Prometheus Query Language)和Loki LogQL。

表达式通常包含以下组成部分:

  • 指标选择器:指定要查询的指标名称,如 http_requests_total。
  • 标签过滤器:缩小查询范围,如 {job="api-server", method="GET"}。
  • 聚合操作:对数据进行汇总,如 sum()、avg()、max()。
  • 数学运算:对指标值进行算术计算,如 / 1000、* 1024。
  • 函数调用:使用内置函数处理数据,如 rate()、increase()、histogram_quantile()。
表达式示例(PromQL):
# 计算过去5分钟CPU使用率的平均值,按实例分组
avg by(instance) (rate(cpu_usage_seconds_total[5m])) > 0.8

# 计算HTTP 5xx错误率,按服务分组
sum by(service) (rate(http_requests_total{status=~"5.."}[5m])) 
/
sum by(service) (rate(http_requests_total[5m])) > 0.05

3.3 条件:触发告警的阈值与比较

条件定义了表达式的结果与什么阈值进行比较,以及比较的结果如何决定告警状态。Grafana支持多种条件类型:

条件类型 说明 适用场景
阈值条件 将表达式结果与固定数值比较(>、<、>=、<=、==、!=) CPU > 90%、内存 < 10%
范围条件 检查表达式结果是否在某个区间内 错误率在 1%~5% 之间
缺失数据条件 当数据源返回空结果或无数据时触发 服务心跳丢失、指标采集中断
经典条件 基于Prometheus的告警规则语法,支持多条件组合 同时满足CPU高且内存高
常见陷阱:在参数化测试中,浮点数精度是导致条件判断失败的主要原因。例如,阈值设为 0.8,但表达式返回 0.8000001,可能导致条件误判。建议在测试中覆盖边界值附近的浮点数场景。

3.4 持续时间:防止告警抖动

持续时间(Duration)是告警规则中防止“抖动”的关键机制。它定义了条件必须连续满足多长时间,才会真正触发告警。这避免了因瞬时波动导致的误报。

持续时间的工作流程如下:

  1. 首次满足:条件第一次满足时,规则进入“待定”(Pending)状态。
  2. 持续计时:每次评估时,如果条件仍然满足,计时器继续累加。
  3. 触发告警:当计时器达到设定的持续时间,规则进入“触发”(Firing)状态,生成告警实例。
  4. 重置计时:如果在持续时间内条件不再满足,计时器重置为0,规则回到“正常”(Normal)状态。
告警状态转换与持续时间机制 正常 (Normal) 条件不满足 待定 (Pending) 计时中: 0s → 持续时间 触发 (Firing) 告警实例已生成 条件满足 计时达到 条件恢复,计时重置 条件恢复,告警自动解决 💡 持续时间是降噪的第一道防线。生产环境中建议设置为 2~5 分钟,避免因瞬时毛刺导致告警风暴。

3.5 标签与注释:告警的元数据与上下文

标签(Labels)和注释(Annotations)是告警实例的“身份证”和“说明书”。它们为告警提供了丰富的上下文信息,便于分类、路由和通知。

3.5.1 标签(Labels)

标签是键值对,用于标识告警的来源和属性。标签直接影响告警的去重和路由。具有相同标签集的告警被视为同一个告警实例。

标签来源 说明 示例
查询结果标签 从PromQL/Loki查询结果中继承的标签 instance="web-01", job="api"
自定义标签 在规则中手动添加的静态标签 severity="critical", team="infra"
模板标签 使用Go模板语法动态生成的标签 env="{{ $labels.environment }}"

3.5.2 注释(Annotations)

注释也是键值对,但用于提供人类可读的信息,如告警描述、修复步骤、Runbook链接等。注释不会影响告警的去重和路由。

标签与注释的典型配置:
# 标签:用于路由和去重
labels:
  severity: critical
  team: platform
  environment: production

# 注释:用于通知和排查
annotations:
  summary: "{{ $labels.instance }} CPU 使用率超过 90%"
  description: "实例 {{ $labels.instance }} 的 CPU 使用率已达到 {{ $value | humanizePercentage }},持续超过 5 分钟。"
  runbook_url: "https://wiki.company.com/runbooks/high-cpu"
  dashboard_url: "https://grafana.company.com/d/abc123?var-instance={{ $labels.instance }}"

3.6 规则结构总览

以下SVG图展示了告警规则各要素之间的完整关系:

告警规则六要素结构图 告警规则 规则定义 表达式 PromQL / LogQL 条件 阈值 / 范围 / 缺失 持续时间 防抖动计时器 标签 (Labels) 去重 / 路由 注释 (Annotations) 描述 / Runbook 告警实例 (Alert Instance) 标签集 + 注释 + 状态 + 时间戳 🔑 标签决定告警的唯一性,注释提供可操作性。在参数化测试中,标签组合是测试用例设计的关键维度。

3.7 参数化测试切入点

基于以上六要素,在后续章节中我们将对以下参数进行系统化的测试验证:

  • 表达式参数:查询时间范围、聚合粒度、函数参数。
  • 条件参数:阈值边界值、比较运算符、多条件组合。
  • 持续时间参数:0s(无防抖)、短持续时间(30s)、长持续时间(10min)。
  • 标签参数:标签数量、标签值长度、特殊字符、动态模板。
  • 注释参数:模板变量解析、URL格式、Markdown渲染。