跳转到主要内容

使用场景

系统在以下场景分派故障时会使用模板:
场景说明
手动创建故障手动创建故障并分派
自动生成故障上报告警事件,系统自动生成故障,按匹配到的分派策略进行分派
重新分派故障创建后,手动更改分派
升级分派根据分派策略设置,系统自动升级分派
重开分派故障关闭后重新打开,按照之前的设置重新分派
系统使用 Golang 模板语法 解析数据,支持逻辑判断、循环、pipeline 及常用函数。更多函数请参考 sprig 函数库

配置模板

1

创建自定义模板

进入 模板管理 页面,点击 创建自定义模板复制默认模板
2

编辑模板内容

按通知渠道编辑对应内容,可引用下方变量列表中的字段
3

保存模板

点击 保存 完成创建

应用模板

1

进入分派策略

前往 协作空间分派策略,点击 编辑
2

选择模板

在策略配置中选择 按照哪个模板 进行通知
3

保存配置

点击 保存 完成配置。详见 配置分派策略

变量引用

引用示例

// 引用故障标题
{{.Title}}

// 引用发起人名称
{{.Creator.PersonName}}

// 引用 resource 标签值
{{.Labels.resource}}

// 引用带 "." 的标签(如 "A.B")
{{index .Labels "A.B"}}

Incident 变量

故障对象的完整变量列表:
字段类型必含说明
IDstring故障 ID
Titlestring故障标题
Descriptionstring故障描述,可能为空
DetailUrlstring故障详情页地址
Numstring故障短标识,仅用于方便肉眼识别
IncidentSeveritystring严重程度:Critical / Warning / Info
IncidentStatusstring故障状态:Critical / Warning / Info / Ok
Progressstring处理进度:Triggered / Processing / Closed
StartTimeint64触发时间,Unix 秒时间戳
LastTimeint64最新事件时间,Unix 秒时间戳
EndTimeint64恢复时间,Unix 秒时间戳
SnoozedBeforeint64暂缓截止时间,Unix 秒时间戳
AckTimeint64首次认领时间,Unix 秒时间戳
CloseTimeint64关闭时间,Unix 秒时间戳
CreatorPerson发起人信息,系统自动生成时不存在
CloserPerson关闭人信息,故障自动恢复时不存在
AssignedToAssignment分派配置
Responders[]Responder处理人列表
ChannelIDint64协作空间 ID
ChannelNamestring协作空间名称
GroupMethodstring聚合方式:n(不聚合)/ p(按规则)/ i(智能)
Labelsmap标签 KV,Key 和 Value 均为字符串
AlertCntint64关联告警个数
Alerts[]Alert关联告警详情
FireTypestring通知类型:fire(通知)/ refire(循环通知)
IsFlappingbool是否处于抖动状态
Impactstring故障影响,关闭后填写
RootCausestring故障根因,关闭后填写
Resolutionstring解决办法,关闭后填写

关联对象

字段类型必含说明
person_idint64人员 ID
person_namestring人员名称
emailstring邮件地址
字段类型必含说明
PersonIDs[]string人员 ID 列表,仅当按人员分派时存在
EscalateRuleIDstring分派策略 ID
EscalateRuleNamestring分派策略名称
LayerIdxstring分派环节,从 0 开始
Typestring分派类型:assign / reassign / escalate / reopen
字段类型必含说明
PersonIDint64人员 ID
PersonNamestring人员名称
Emailstring邮件地址
AssignedAtint64分派时间,Unix 秒时间戳
AcknowledgedAtint64认领时间,Unix 秒时间戳
字段类型必含说明
Titlestring告警标题
Descriptionstring告警描述,可能为空
AlertSeveritystring严重程度:Critical / Warning / Info
AlertStatusstring告警状态:Critical / Warning / Info / Ok
Progressstring处理进度:Triggered / Processing / Closed
StartTimeint64触发时间,Unix 秒时间戳
EndTimeint64恢复时间,Unix 秒时间戳
CloseTimeint64关闭时间,Unix 秒时间戳
Labelsmap标签 KV

常见问题

  • 手动创建的故障没有标签
  • 自动创建的故障存在标签,与合入的第一条告警的标签相同
前往 故障列表 → 查看故障详情,可以看到全部标签信息。
创建自定义模板时,系统使用 mock 数据检查语法。mock 数据覆盖场景有限,实际运行时可能渲染失败,系统将使用默认模板兜底。
建议在引用变量前先判断是否存在:
// ❌ 错误:直接读取标签
{{.Labels.resource}}

// ✅ 推荐:先判断再读取
{{if .Labels.resource}}{{.Labels.resource}}{{end}}
使用 toHtml 函数处理:
// 转义 HTML 字符
{{toHtml .Title}}

// 使用第一个不为空的值渲染
{{toHtml .Title .TitleEnglish}}
// date 函数:将时间戳转换为可读格式
{{date "2006-01-02 15:04:05" .StartTime}}

// ago 函数:将时间差转换为可读格式(如 "5 分钟前")
{{ago .StartTime}}
在外部变量前增加 $
{{range .Responders}}
  {{if eq $.Progress "Triggered"}}
待处理】{{.Email}}
  {{end}}
{{end}}
使用 index 函数:
{{index .Labels "obj.instance"}}
// alertLabels:得到去重后的数组
{{alertLabels . "resource"}}

// joinAlertLabels:去重后按分隔符拼接为字符串
{{joinAlertLabels . "resource" ", "}}
// 完整遍历
{{range $k, $v := .Labels}}
  {{$k}} : {{toHtml $v}}
{{end}}

// 排除单个 label
{{range $k, $v := .Labels}}
  {{if ne $k "resource"}}
    {{$k}} : {{toHtml $v}}
  {{end}}
{{end}}

// 排除多个 labels
{{range $k, $v := .Labels}}
  {{if not (in $k "resource" "body_text")}}
    {{$k}} : {{toHtml $v}}
  {{end}}
{{end}}
使用 jsonGet 函数从合法 JSON 中按 path 提取值。语法参考 gjson.dev
// 提取 rule_note 标签中的 detail_url 字段
{{jsonGet .Labels.rule_note "detail_url"}}

// 提取 JSON 数组中第一个元素的 name 字段
{{jsonGet .Labels.slice "0.name"}}

// 遍历数组,匹配 userId==7777 的 instanceId 字段
{{jsonGet .Labels.rule_note "#(userId==7777)#.instanceId"}}
imageSrcToURL:将 image_key 或 URL 转换为可访问地址(钉钉/Slack App 使用)
{{ $root := . }}
{{ range $i, $v := .Images }}
  {{ $imageURL := imageSrcToURL $root $v.Src }}
  {{ if $imageURL }}![]({{$imageURL}}){{ end }}
{{ end }}
transferImage:上传图片到第三方平台(飞书/Lark App 使用)
{{ $root := . }}
{{ range $i, $v := .Images }}
  {{ $transferURL := transferImage $root $v.Src }}
  {{ if $transferURL }}![]({{$transferURL}}){{ end }}
{{ end }}
图片大小不能超过 10 MB,支持 JPG、PNG、WEBP、GIF、BMP 等格式。
函数说明示例
and逻辑与{{if and (eq .A "x") (eq .B "y")}}
or逻辑或{{if or (eq .A "x") (eq .A "y")}}
not逻辑非{{if not (eq .A "x")}}
eq等于{{if eq .A "x"}}
ne不等于{{if ne .A "x"}}
gt / ge大于 / 大于等于{{if gt .AlertCnt 1}}
lt / le小于 / 小于等于{{if lt .AlertCnt 10}}

渠道模板

不同通知渠道支持的模板格式和限制不同。
需预先配置 飞书集成。支持消息卡片格式,系统会自动删除因标签不存在导致的渲染空行。默认模板(渲染全部标签):
{{if .Labels.body_text}}{{.Labels.body_text}}{{else if .Description}}{{.Description}}{{end}}
{{if .Labels.resource}}**resource** : {{(joinAlertLabels . "resource" ", ")}}{{end}}
{{range $k, $v := .Labels}}
{{if not (in $k "resource" "body_text" "body_text_with_table")}}**{{$k}}** : {{$v}}{{end}}{{end}}
{{ $root := . }}
{{ range $i, $v := .Images }}
  {{ $transferURL := transferImage $root $v.Src }}
  {{ if $transferURL }}![]({{$transferURL}}){{ end }}
{{ end }}
飞书应用通知

飞书应用通知效果

精简模板(仅展示关键标签):
{{if (index .Labels "resource")}}resource:{{toHtml (joinAlertLabels . "resource" ", ")}}{{end}}
{{if (index .Labels "check")}}check:{{toHtml (index .Labels "check")}}{{end}}
{{if (index .Labels "metric")}}metric:{{index .Labels "metric"}}{{end}}
{{if (index .Labels "trigger_value")}}trigger_value:{{index .Labels "trigger_value"}}{{end}}
{{if (index .Labels "region")}}region:{{index .Labels "region"}}{{end}}
{{if (index .Labels "cluster")}}cluster:{{index .Labels "cluster"}}{{end}}
{{if (index .Labels "service")}}service:{{index .Labels "service"}}{{end}}
{{if (index .Labels "env")}}env:{{index .Labels "env"}}{{end}}

机器人模板

群聊机器人支持的模板格式。
支持消息卡片、富文本和普通文本三种格式。消息最大 4000 字节,超出后截断。
{
  "msg_type": "interactive",
  "card": {
    "config": {
      "wide_screen_mode": true,
      "enable_forward": true
    },
    "header": {
      "template": "{{if eq .IncidentSeverity \"Critical\"}}red{{else if eq .IncidentSeverity \"Warning\"}}orange{{else}}yellow{{end}}",
      "title": {
        "content": "{{fireReason .}}INC #{{.Num}} {{toHtml .Title}}",
        "tag": "plain_text"
      }
    },
    "elements": [{
      "tag": "div",
      "fields": [{
        "text": {
          "tag": "lark_md",
          "content": "**🏢 协作空间:**{{.ChannelName}}"
        }
      },
      {
        "text": {
          "tag": "lark_md",
          "content": "**⏰ 触发时间:**{{date \"2006-01-02 15:04:05\" .StartTime}}"
        }
      }]
    },
    {
      "tag": "action",
      "actions": [{
        "tag": "button",
        "text": { "tag": "plain_text", "content": "故障详情" },
        "type": "primary",
        "url": "{{.DetailUrl}}"
      },
      {
        "tag": "button",
        "text": { "tag": "plain_text", "content": "认领" },
        "type": "primary",
        "url": "{{.DetailUrl}}?ack=1"
      }]
    }]
  }
}
{
  "msg_type": "post",
  "post": {
    "zh_cn": {
      "title": "{{if eq .IncidentSeverity \"Critical\"}}🔴{{else if eq .IncidentSeverity \"Warning\"}}⚠️{{else}}ℹ️{{end}} {{fireReason .}}INC #{{.Num}} {{toHtml .Title}}",
      "content": [
        [{"tag": "text", "text": "🏢 "}, {"tag": "text", "text": "协作空间:", "style": ["bold"]}, {"tag": "text", "text": "{{.ChannelName}}"}],
        [{"tag": "text", "text": "⏰ "}, {"tag": "text", "text": "触发时间:", "style": ["bold"]}, {"tag": "text", "text": "{{date \"2006-01-02 15:04:05\" .StartTime}}"}],
        [{"tag": "a", "href": "{{.DetailUrl}}", "text": "故障详情"}, {"tag": "text", "text": "  "}, {"tag": "a", "href": "{{.DetailUrl}}?ack=1", "text": "认领"}]
      ]
    }
  }
}
{{fireReason .}}INC #{{.Num}} {{toHtml .Title}}
-----
协作空间:{{if .ChannelName}}{{.ChannelName}}{{else}}{{end}}
严重程度:{{.IncidentSeverity}}
触发时间:{{date "2006-01-02 15:04:05" .StartTime}}
持续时长:{{ago .StartTime}}
<br />详情:{{.DetailUrl}}

其他渠道

默认模板
您有故障待处理:{{toHtml .Title}},协作空间:{{.ChannelName}},等级:{{.IncidentSeverity}}{{if gt .AlertCnt 1}},共聚合{{.AlertCnt}}条告警{{end}}

延伸阅读