Provision 告警规则、联系点与通知策略
用 YAML 定义整条告警管线,使其像代码一样被审查和版本化。
Grafana 告警有四个活动部件:告警规则判断何时出了问题,联系点说明通知发往何处,通知策略将告警路由到联系点,静默时段和模板则决定消息何时、以何种方式发出。这四者都可以通过 provisioning/alerting 文件夹中的 YAML 进行 provision,这使告警可审查,而不是一堆 UI 设置。本指南构建一条小型的可用管线。
被 provision 的告警资源无法在 UI 中编辑,并且导入已存在的资源会造成冲突,所以请先移除手工创建的重复项。每个文件都以 apiVersion: 1 开头。
联系点
provisioning/alerting/contact-points.yaml:
apiVersion: 1
contactPoints:
- orgId: 1
name: team-slack
receivers:
- uid: team-slack-1
type: slack
disableResolveMessage: false
settings:
url: ${SLACK_WEBHOOK_URL}
recipient: '#alerts'
- orgId: 1
name: oncall-email
receivers:
- uid: oncall-email-1
type: email
settings:
addresses: oncall@example.com
说明:
- 每个 receiver 上的
uid必须唯一且稳定。Grafana 用它来原地更新该 receiver。 type是集成类型,例如slack、email、webhook、pagerduty、opsgenie或prometheus-alertmanager。settings下的键取决于类型,所以请查阅你所用类型的文档。- 密钥通过
$VAR或${VAR}来自环境变量,所以 webhook URL 永远不会存在于 Git 中。用$$保留字面的美元符号。 - 要移除某个联系点,添加
deleteContactPoints,并附上它的orgId和uid。
通知策略
策略树决定哪个联系点处理哪个告警。整棵树是一个资源,并且 provision 它会覆盖所有现有策略。
provisioning/alerting/policies.yaml:
apiVersion: 1
policies:
- orgId: 1
receiver: team-slack # default for anything not matched below
group_by: ['alertname', 'namespace']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
routes:
- receiver: oncall-email
object_matchers:
- ['severity', '=', 'critical']
repeat_interval: 1h
- receiver: team-slack
object_matchers:
- ['team', '=', 'platform']
mute_time_intervals:
- weekends
- 顶层的
receiver是兜底的联系点。 group_by将相关的告警批量合并为一条通知。group_wait、group_interval、repeat_interval控制第一条消息多快发出、某个组多久发送一次更新,以及未解决的告警多久重复一次。routes是使用相同字段的子策略。除非设置continue: true,否则第一个匹配的路由获胜。object_matchers是[label, operator, value]三元组。操作符有=、!=、=~和!~。
要将树重置为 Grafana 的默认值,请使用 resetPolicies: [1] 并带上组织 ID。
静默时段
apiVersion: 1
muteTimes:
- orgId: 1
name: weekends
time_intervals:
- weekdays: ['saturday', 'sunday']
location: 'UTC'
times(带 start_time 和 end_time)、weekdays、months、years 和 days_of_month 可以组合使用,范围使用冒号,例如 'monday:friday'。用 deleteMuteTimes 删除。静默时段的名称和间隔不能使用变量插值。
通知模板
apiVersion: 1
templates:
- orgId: 1
name: slack_title
template: |
{{ define "slack_title" }}
[{{ .Status | toUpper }}] {{ .CommonLabels.alertname }}
{{ end }}
在联系点的设置中引用模板(例如 Slack 的 title 字段),写作 {{ template "slack_title" . }}。模板的名称和内容不支持变量插值,所以请按字面书写。
告警规则
规则被组织成组,共享一个评估间隔并位于一个文件夹中。每条规则都有一个查询与表达式步骤的列表,以及一个指明由哪一步决定是否触发的 condition。
provisioning/alerting/rules.yaml:
apiVersion: 1
groups:
- orgId: 1
name: webapp
folder: Applications
interval: 1m
rules:
- uid: webapp-down
title: Webapp targets down
condition: C
for: 5m
noDataState: NoData
execErrState: Error
labels:
severity: critical
team: platform
annotations:
summary: 'No healthy webapp targets for 5 minutes'
runbook_url: https://runbooks.example.com/webapp-down
data:
- refId: A
relativeTimeRange:
from: 600
to: 0
datasourceUid: prometheus
model:
refId: A
expr: sum(up{job="webapp"})
instant: true
- refId: B
datasourceUid: __expr__
model:
refId: B
type: reduce
expression: A
reducer: last
datasource:
type: __expr__
uid: __expr__
- refId: C
datasourceUid: __expr__
model:
refId: C
type: threshold
expression: B
conditions:
- evaluator:
type: lt
params: [1]
datasource:
type: __expr__
uid: __expr__
如何阅读它:
- 步骤 A 通过你 provision 的数据源
uid,向 Prometheus 查询过去十分钟内健康目标的数量。relativeTimeRange以秒为单位。 - 步骤 B 将结果 reduce 为单个值。表达式使用特殊的数据源 UID
__expr__。 - 步骤 C 是一个阈值:当值小于 1 时触发。
condition: C将它标记为决定性步骤。 for: 5m要求条件持续五分钟才触发告警,以避免抖动。noDataState和execErrState说明当查询没有返回数据或失败时怎么办:前者可选NoData、Alerting或OK,后者可选Error、Alerting或OK。labels馈入通知策略树,所以severity: critical正是让这条告警走向上面oncall-email路由的原因。uid(最多 40 个字符,可含字母、数字、-和_)必须唯一且稳定。可选地添加dashboardUid和panelId,将规则链接到某个面板。- 文件夹: 使用一个已存在的文件夹。最简单的方式是复用你的仪表板 provider 所创建文件夹的标题。
变量插值在规则注解、relativeTimeRange、查询 model 或模板内容中不起作用,所以请把这些值写出来。
要删除某条规则,添加 deleteRules,并附上它的 orgId 和 uid:
apiVersion: 1
deleteRules:
- orgId: 1
uid: webapp-down
应用与验证
告警资源在启动时读取,所以更改文件之后请重启 Grafana:
docker compose restart grafana
curl -s -u admin:$GRAFANA_ADMIN_PASSWORD \
http://localhost:3000/api/v1/provisioning/alert-rules | jq '.[] | {uid, title, folderUID}'
curl -s -u admin:$GRAFANA_ADMIN_PASSWORD \
http://localhost:3000/api/v1/provisioning/contact-points | jq '.[].name'
curl -s -u admin:$GRAFANA_ADMIN_PASSWORD \
http://localhost:3000/api/v1/provisioning/policies | jq .receiver
然后通过暂时降低阈值,或从联系点的 API 发送一条测试通知,来测试投递。
更快地编写规则
规则 YAML 很冗长。在一个临时实例中构建一次规则,然后通过告警 provisioning API(/api/v1/provisioning/ 下带 ?format=yaml 的 export 路由)以 provisioning 格式导出它,并带着稳定的 uid 提交结果。对于许多相似的规则,请在 CI 中从模板生成 YAML,或者使用同样提供告警规则资源的 Terraform 或 Grafana Operator 来管理。
热门指南
-
将 Grafana 作为代码运维:全景图 哪些可以放在文件里,哪些需要 API,以及各部分如何组合在一起。 -
使用 grafana.ini 和环境变量配置 Grafana 服务器 了解配置文件的位置、覆盖的顺序,以及如何将设置保存在 Git 中。 -
从 JSON 文件 Provision 仪表板 从磁盘加载仪表板,从目录映射文件夹,并在不丢失变更的前提下创作仪表板。 -
使用 Helm 和 Provisioning Values 在 Kubernetes 上部署 Grafana 通过 Helm chart 运行 Grafana,数据源、仪表板和设置都来自 values 文件。 -
从命令行重新加载、验证并排查 Provisioning 问题 找出 Grafana 加载了什么,无需重启即可重新加载,并修复常见的 provisioning 错误。