3. 告警规则数据结构:核心字段解析
在服务目录的 Grafana 告警规则接口调用设计中,理解告警规则的数据结构是构建自动化管理能力的基础。Grafana 告警规则采用四层嵌套结构:Rule Group → Alert Rule → Condition → Data Source Query。每一层承载不同的职责,从规则的组织、触发条件的定义,到数据源的查询逻辑,层层递进。
核心认知: 告警规则并非扁平结构。Rule Group 是顶层容器,Alert Rule 是规则主体,Condition 是判定逻辑,Data Source Query 是数据来源。接口调用时,必须按此层级构造请求体。
3.1 四层结构总览
下面的 SVG 图展示了告警规则的四层嵌套关系,以及各层之间的包含与引用逻辑:
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 创建失败。