4. 告警通知渠道:Contact Point 配置与通知模板语法
Contact Point(联系人点)是 Grafana 告警引擎将告警实例发送到外部系统的出口。每个 Contact Point 绑定一个或多个通知渠道(Integration),并可通过通知模板(Notification Template)自定义消息载荷。本章覆盖 Email、Slack、PagerDuty、Webhook 四种核心渠道的配置要点,以及 Go 模板语法在告警通知中的实战用法。
4.1 Contact Point 核心概念
| 概念 | 说明 |
|---|---|
| Contact Point | 一组通知渠道的集合,每个渠道可独立配置接收地址与认证信息 |
| Integration | 具体的通知类型,如 Email、Slack Webhook、PagerDuty Events API v2 |
| Notification Template | 基于 Go text/template 的自定义消息模板,可引用告警元数据 |
| Optional Email Settings | 仅 Email 渠道独有,支持 TLS、认证、自定义头等高级选项 |
最佳实践:每个 Contact Point 只绑定一种渠道类型,通过命名区分用途(如
critical-slack、warning-email),便于在 Notification Policy 中按标签路由。
4.2 渠道配置详解
4.2.1 Email
Grafana 使用内置 SMTP 客户端发送告警邮件。配置路径:Alerting → Contact Points → New Contact Point → Email。
| 字段 | 必填 | 说明 |
|---|---|---|
| Addresses | 是 | 收件人邮箱,多个用 ; 或换行分隔 |
| Subject | 否 | 邮件主题,支持模板语法,默认 {{ .Subject }} |
| Message | 否 | 邮件正文,支持 HTML 与模板,默认使用 Grafana 内置模板 |
| Single email | 否 | 勾选后所有告警合并到一封邮件发送 |
SMTP 前置依赖:必须在
grafana.ini 的 [smtp] 段配置 host、user、password、from_address,否则 Email 渠道不可用。
4.2.2 Slack
通过 Slack Incoming Webhook 发送消息。配置时需提供 Webhook URL,Grafana 自动构造消息块(Blocks)或附件(Attachments)。
| 字段 | 必填 | 说明 |
|---|---|---|
| Webhook URL | 是 | Slack App 生成的 Incoming Webhook 地址 |
| Title | 否 | 消息标题,支持模板,默认 {{ .Subject }} |
| Text Body | 否 | 消息正文,支持 Markdown 与模板 |
| Recipient | 否 | 覆盖 Webhook 默认频道,如 #alerts 或 @user |
注意:Slack 对消息块数量有限制(最多 50 个块),当告警标签较多时,建议在模板中使用
range 限制输出条数,避免消息被截断。
4.2.3 PagerDuty
使用 PagerDuty Events API v2 创建事件。需要提供 Integration Key(路由键)。
| 字段 | 必填 | 说明 |
|---|---|---|
| Integration Key | 是 | PagerDuty 服务集成页面的 32 位路由键 |
| Severity | 否 | 映射 Grafana 告警严重级别,支持 critical、error、warning、info |
| Class | 否 | 事件分类,如 cpu_usage,支持模板 |
| Group | 否 | 事件分组键,用于 PagerDuty 聚合,支持模板 |
4.2.4 Webhook
最灵活的渠道,支持自定义 HTTP 请求方法与载荷。适用于自建通知系统、工单系统或 ChatOps 机器人。
| 字段 | 必填 | 说明 |
|---|---|---|
| URL | 是 | 目标 HTTP 端点 |
| HTTP Method | 否 | 默认 POST,可选 PUT |
| HTTP Header | 否 | 自定义请求头,如 Authorization: Bearer xxx |
| Message | 否 | 请求体,支持模板,默认 JSON 格式 |
Webhook 调试技巧:先用 webhook.site 或 RequestBin 生成临时 URL,观察 Grafana 发送的原始载荷,再逐步调整模板。
4.3 通知模板(Notification Template)语法
Grafana 使用 Go text/template 引擎,所有模板上下文(Context)通过 . 传递。核心数据对象为 Alert 结构体,包含告警名称、标签、注解、时间戳、静默/抑制状态等字段。
4.3.1 常用模板变量
| 变量 | 类型 | 说明 |
|---|---|---|
{{ .Subject }} |
string | 告警标题,由 Grafana 自动生成 |
{{ .Message }} |
string | 告警消息正文 |
{{ .Labels }} |
map[string]string | 告警标签,如 severity、team |
{{ .Annotations }} |
map[string]string | 告警注解,如 summary、runbook_url |
{{ .StartsAt }} |
time.Time | 告警触发时间 |
{{ .EndsAt }} |
time.Time | 告警结束时间(未解决时为 0001-01-01) |
{{ .Silenced }} |
bool | 是否被静默 |
{{ .Inhibited }} |
bool | 是否被抑制 |
4.3.2 模板函数与管道
Grafana 内置了丰富的模板函数,常用函数如下:
| 函数 | 示例 | 说明 |
|---|---|---|
title |
{{ .Labels.severity | title }} |
首字母大写 |
upper |
{{ .Labels.env | upper }} |
全部大写 |
lower |
{{ .Labels.team | lower }} |
全部小写 |
default |
{{ .Labels.owner | default "unassigned" }} |
空值时使用默认值 |
humanizeDuration |
{{ .StartsAt | humanizeDuration }} |
将时间差转为可读字符串(如 "5m30s") |
match |
{{ if match "critical" .Labels.severity }}🚨{{ end }} |
正则匹配 |
4.3.3 模板示例:Slack 消息自定义
{{ define "slack_custom" }}
{
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "{{ .Subject }}"
}
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Severity:*\n{{ .Labels.severity | upper }}"
},
{
"type": "mrkdwn",
"text": "*Team:*\n{{ .Labels.team | default "platform" }}"
}
]
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "{{ .Annotations.summary }}"
}
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "View Runbook"
},
"url": "{{ .Annotations.runbook_url }}"
}
]
}
]
}
{{ end }}
4.4 通知模板与 Contact Point 绑定流程
4.5 模板管理最佳实践
- 模板复用:在 Grafana 的 Alerting → Contact Points → Templates 中创建全局模板,使用
{{ define "template_name" }}定义,在 Contact Point 中通过{{ template "template_name" . }}引用。 - 版本控制:将模板代码存储在 Git 仓库中,通过 Grafana Provisioning 的
alerting.templates配置自动同步。 - 测试验证:使用
grafana-cli alerting test-template命令或 Grafana APIPOST /api/v1/alert-templates/test在部署前验证模板输出。 - 避免敏感信息:不要在模板中硬编码 、密码等敏感信息,应通过环境变量或 Secret 管理工具注入。
实战案例:某团队在 Slack 渠道中通过模板动态插入 Runbook 链接,当告警标签
runbook_id 存在时,自动拼接 https://runbook.internal/{{ .Labels.runbook_id }},减少运维人员查找文档的时间。
4.6 多渠道对比与选型建议
| 渠道 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 非紧急告警、合规审计 | 通用性强、可归档 | 延迟高、易被过滤 | |
| Slack | 团队协作、日常告警 | 实时、支持交互按钮 | 消息量大会造成噪音 |
| PagerDuty | 关键告警、值班轮换 | 自动升级、确认/关闭流程 | 需要额外付费 |
| Webhook | 自定义集成、工单系统 | 完全可控、任意格式 | 需要自建接收端 |
推荐组合:Critical 告警 → PagerDuty + Slack(@channel);Warning 告警 → Slack(#alerts);Info 告警 → Email。通过 Notification Policy 的标签匹配实现分级路由。