3. 告警规则数据结构:核心字段解析

在服务目录的 Grafana 告警规则接口调用设计中,理解告警规则的数据结构是构建自动化管理能力的基础。Grafana 告警规则采用四层嵌套结构:Rule Group → Alert Rule → Condition → Data Source Query。每一层承载不同的职责,从规则的组织、触发条件的定义,到数据源的查询逻辑,层层递进。

核心认知: 告警规则并非扁平结构。Rule Group 是顶层容器,Alert Rule 是规则主体,Condition 是判定逻辑,Data Source Query 是数据来源。接口调用时,必须按此层级构造请求体。

3.1 四层结构总览

下面的 SVG 图展示了告警规则的四层嵌套关系,以及各层之间的包含与引用逻辑:

告警规则四层嵌套结构 Rule Group(规则组) name / folderUID / interval / rules[] 组织单元:按文件夹分组,共享评估间隔 Alert Rule(告警规则) uid / title / condition / data[] / noDataState / execErrState 规则主体:定义告警名称、引用条件、关联数据查询 Condition(条件) type / evaluator / operator / queries[] / reducer 判定逻辑:组合多个查询结果,执行阈值评估 Data Source Query(数据源查询) refId / datasourceUid / queryType / rawQuery 数据获取:指定数据源、查询语句、时间范围

3.2 Rule Group(规则组)核心字段

Rule Group 是告警规则的顶层容器,对应 Grafana 中“文件夹”级别的组织单元。在 Prometheus 兼容模式下,一个 Rule Group 包含一组共享评估间隔的告警规则。

字段名 类型 必填 说明
name string 是 规则组名称,在同一文件夹内唯一
folderUID string 是 所属文件夹的 UID,用于权限继承和分组管理
interval string 否 评估间隔,如 "1m"、"30s";默认继承 Grafana 全局配置
rules array 是 包含的告警规则列表,至少 1 条
接口设计提示: 创建告警规则时,必须先确保 folderUID 对应的文件夹存在。Grafana API 不允许在根目录直接创建 Rule Group,必须指定文件夹。

3.3 Alert Rule(告警规则)核心字段

Alert Rule 是告警规则的主体,定义了告警的元信息、触发条件引用、数据查询列表以及异常状态处理策略。

字段名 类型 必填 说明
uid string 否(创建时自动生成) 规则唯一标识,更新时必须携带
title string 是 告警规则名称,用于告警消息展示
condition string 是 引用 data[] 中某个查询的 refId,作为最终判定条件
data array 是 数据查询列表,至少包含 1 个查询对象
noDataState string 否 无数据时的状态:NoData / Alerting / OK,默认 NoData
execErrState string 否 执行错误时的状态:Error / Alerting / OK,默认 Error
for string 否 持续时间要求,如 "5m",满足条件持续该时长后才触发告警
annotations object 否 告警附加信息,如 summary、description、runbook_url
labels object 否 标签键值对,用于告警路由、分组和静默
常见误区: condition 字段的值必须与 data[] 中某个查询对象的 refId 完全一致。如果引用不存在的 refId,Grafana 会返回 400 错误。另外,for 字段的格式必须符合 Prometheus 持续时间规范(如 "5m"、"1h"),不支持 "5 minutes" 这种自然语言格式。

3.4 Condition(条件)核心字段

Condition 是告警规则的判定逻辑层,它不是一个独立的 API 对象,而是嵌入在 data[] 数组中的特殊查询类型(refId 被 condition 字段引用)。Condition 负责将多个数据源查询的结果进行组合、归约和阈值评估。

字段名 类型 必填 说明
refId string 是 条件引用的标识符,必须与 Alert Rule 的 condition 字段一致
queryType string 是 固定为 "__expr__",表示这是一个表达式/条件节点
model.type string 是 条件类型:classic_condition / reduce / math / threshold / resample
model.evaluator object 条件类型相关 阈值评估器:type(gt/lt/within_range/outside_range) + params[]
model.operator object 否 多条件组合运算符:and / or
model.reducer object 条件类型相关 归约函数:avg / min / max / sum / count / last / median

常见的 Condition 类型及其用途:

  • classic_condition:经典条件,支持多查询组合,每个查询独立评估后通过 operator 组合
  • reduce:归约操作,将时间序列数据归约为单个值(如取平均值)
  • math:数学表达式,对多个查询结果进行算术运算
  • threshold:阈值判定,将归约后的值与阈值进行比较
  • resample:重采样,将不同时间粒度的数据对齐到统一时间窗口
最佳实践: 在服务目录场景中,推荐使用 reduce + threshold 组合模式。先通过 reduce 将指标数据归约为单一数值,再通过 threshold 进行阈值判定。这种模式逻辑清晰,便于在 API 调用时进行参数化配置。

3.5 Data Source Query(数据源查询)核心字段

Data Source Query 是告警规则的数据获取层,定义了从哪个数据源、使用什么查询语句、在什么时间范围内获取指标数据。一个告警规则可以包含多个数据源查询,通过 Condition 进行组合。

字段名 类型 必填 说明
refId string 是 查询引用标识符,在 data[] 数组内唯一,如 "A"、"B"、"C"
datasourceUid string 是 数据源实例的 UID,通过 Grafana API 获取
queryType string 是 查询类型,如 "range"(范围查询)、"instant"(瞬时查询)
model object 是 查询模型,包含数据源特定的查询参数(如 PromQL、SQL)
relativeTimeRange object 否 相对时间范围:from(如 600 表示过去 600 秒)、to(通常为 0)

以 Prometheus 数据源为例,model 字段的典型结构:

{
  "refId": "A",
  "datasourceUid": "prometheus-uid-123",
  "queryType": "range",
  "model": {
    "expr": "avg(rate(http_requests_total{status=~"5.."}[5m]))",
    "intervalMs": 15000,
    "maxDataPoints": 100,
    "legendFormat": "5xx_rate"
  },
  "relativeTimeRange": {
    "from": 600,
    "to": 0
  }
}

3.6 完整请求体示例

以下是一个完整的创建告警规则 API 请求体,展示了四层结构的实际组合方式:

{
  "name": "生产环境-5xx告警组",
  "folderUID": "folder-abc-123",
  "interval": "1m",
  "rules": [
    {
      "title": "5xx错误率过高",
      "condition": "C",
      "noDataState": "NoData",
      "execErrState": "Error",
      "for": "5m",
      "annotations": {
        "summary": "5xx错误率超过阈值",
        "description": "当前5xx错误率 {{ $values.B }}%,阈值 5%"
      },
      "labels": {
        "severity": "critical",
        "team": "sre"
      },
      "data": [
        {
          "refId": "A",
          "datasourceUid": "prometheus-uid-123",
          "queryType": "range",
          "model": {
            "expr": "sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) * 100",
            "intervalMs": 15000,
            "maxDataPoints": 100
          },
          "relativeTimeRange": {
            "from": 600,
            "to": 0
          }
        },
        {
          "refId": "B",
          "queryType": "__expr__",
          "model": {
            "type": "reduce",
            "reducer": "last",
            "expression": "A"
          }
        },
        {
          "refId": "C",
          "queryType": "__expr__",
          "model": {
            "type": "threshold",
            "evaluator": {
              "type": "gt",
              "params": [5.0]
            },
            "expression": "B"
          }
        }
      ]
    }
  ]
}
接口调用要点: 上述示例中,data[] 数组包含 3 个元素:A 是 Prometheus 查询,B 是 reduce 归约,C 是 threshold 阈值判定。condition 字段指向 C,表示最终以 C 的评估结果作为告警触发依据。这种“查询 → 归约 → 判定”的三段式结构是 Grafana 告警规则的推荐模式。

3.7 字段校验规则速查

在服务目录的 API 调用中,字段校验失败是最常见的错误来源。下表总结了关键校验规则:

层级 字段 校验规则 错误示例
Rule Group name 长度 1-190 字符,不可包含控制字符 空字符串、包含 \n
Rule Group folderUID 必须指向已存在的文件夹 不存在的 UID
Alert Rule title 长度 1-190 字符,在同一 Rule Group 内唯一 重复标题
Alert Rule condition 必须匹配 data[] 中某个元素的 refId condition: "D" 但 data[] 中无 refId 为 D
Condition model.evaluator.params params 数组长度和类型必须与 evaluator.type 匹配 gt 类型传了 2 个参数
Data Source Query datasourceUid 必须指向已配置的数据源 不存在的 UID 或已删除的数据源
Data Source Query model.expr 对于 Prometheus 数据源,expr 必须为合法 PromQL 语法错误的 PromQL
生产环境注意事项: 在服务目录的批量创建场景中,建议先通过 Grafana API 的 /api/v1/provisioning/folder/{folderUID}/rule-groups 端点进行 dry-run 验证,确认所有字段校验通过后再执行实际创建。这可以避免因单条规则校验失败导致整个 Rule Group 创建失败。