新版告警支持两个版本的内容模板语法。本文介绍新版内容模板语法。
概述
相对于旧版的内容模板语法,新版通过类似 Python 语法的方式,提供更加灵活且高级的自定义渲染逻辑,在定制通知内容(例如 Markdown 转义)、自定义内容样式等方面都做了优化,满足更多样化的定制内容需求。例如:
-
根据告警的严重度进行动态的内容渲染,不同严重度使用不同颜色的文字进行区分。
-
对告警的查询结果进行迭代渲染,在邮件中渲染为列表或者表格。
-
通过函数对某个字段进行 BASE64 编码和解码、对数值进行数学运算等。
新版的内容模板语法完全兼容旧版,并支持新旧版混合使用。但在不同版本的内容模板语法中使用告警属性时,其类型、取值和展示形式等存在差异,因此建议您不要混合使用新旧版本的内容模板语法。推荐您使用新版本的内容模板语法。
快速开始
通过新版内容模板定义通知内容的示例如下:
-
告警内容
{ "alert_id": "test-alert", "alert_name": "PV/UV Alert", "project": "project-1", "status": "firing", "severity": 6, "labels": { "app": "nginx", "host": "host-1" "results": [ "project": "project-1", "logstore": "logstore-1", "query": "* | select count(*) as pv" "project": "project-2", "logstore": "logstore-2", "query": "* | select count(distinct user_id) as uv" }
-
内容模板配置
- Alert ID: {{ alert.alert_id }} - Alert Name: {{ alert.alert_name }} - Project: {{ alert.project }} - Status: {% if alert.status == "firing" %}FIRING{% else %}RESOLVED{% endif %} - Labels: {%- for key, val in alert.labels.items() %} - {{ key }}: {{ val }} {%- endfor %} - Query: {{ alert.results[0].query }}
-
输出结果
- Alert ID: test-alert - Alert Name: PV/UV Alert - Project: project-1 - Status: FIRING - Labels: - app: nginx - host: host-1 - Query: * | select count(*) as pv
基本语法
数据类型
内容模板语法类似于 Python 语法,支持如下数据类型。
数据类型 |
说明 |
数字 |
包含整数和浮点数。例如 3、-1。 |
字符串 |
需要使用单引号('')或者双引号("")包裹。例如"foo"、'bar'。
当字符串中存在特殊字符时,需使用反斜线(\)进行转义。例如
|
布尔值 |
True、False。 |
空值 |
None。 |
列表 |
不同编程语言中的叫法不同,可以为列表、数组、Slice 等。例如['foo', 'bar']。 |
字典 |
不同编程语言中的叫法不同,可以为字典、对象等。例如{'foo': 'bar'}。 |
分隔符
分隔符 |
使用场景 |
示例 |
|
在变量或表达式中使用。 |
|
|
用于控制语句。 |
|
|
用于注释,不会出现在通知内容中。 |
|
清除空字符
默认情况下,在分隔符内部,分隔符与表达式之间的空格会被忽略。例如
{{ 23 }} < {{ 45 }}
等同于
{{23}} < {{45}}
,渲染结果都为
23 < 45
。但是分隔符外部的空字符(空格、Tab、换行等)会被保留,例如
{{ 23 }} < {{ 45 }}
的渲染结果为
23 < 45
,而不是
23<45
。
当您需要删除多余的空字符时,可以使用清除空字符操作。在分隔符开始或结束的地方添加一个短划线(-),用于清除该分隔符前面和后面所有紧连着的空字符。例如
{{ 23 -}} < {{- 45 }}
的渲染结果为
23<45
。
-
{{-
、{{%-
、{#-
用于删除分隔符左侧紧连着的所有空字符。 -
-}}
、-%}
、-%}
用于删除分隔符右侧紧连着的所有空字符。
-
短划线(-)和分隔符之间不能有空格。例如
{{- 3 }}
是有效的,渲染结果为3
;{{ - 3 }}
是无效的,渲染结果为-3
。 -
清除空字符操作只对分隔符外部的空格有效,不影响分隔符内部的空格。例如
{{ "hello " }} {{- "world"}}
渲染结果为hello world
。
条件语句
条件判断支持对参数或者逻辑比较表达式进行判断。通过条件判断,可以进行动态渲染。
-
如果
if
后面传入的是常量或者普通变量,则对该值进行真值判断。其中布尔值false
、数字0
、空字符串""
、空值null
、空数组[]
、空对象{}
都会被判定为假,其它值被判定为真。 -
如果
if
后面传入的是逻辑比较表达式,则按照比较结果进行判断。例如{{ if alert.severity >= 8 }}
用于判断告警严重度是否大于等于 8。
条件判断支持如下几种形式:
使用方式 |
示例 |
if |
|
if-else |
|
if-elif |
|
if-elif-else |
|
嵌套使用 |
|
迭代
循环语句用于对数组和对象进行迭代操作。支持如下几种使用方式:
使用方式 |
示例 |
数组迭代 |
|
数组迭代,包含下标 |
使用 enumerate 函数对数组进行下标迭代。关于 enumerate 函数的更多信息,请参见 enumerate 函数 。
下标默认从 0 开始。您也可以通过 enumerate 函数中的 start 参数自定义起始下标。例如:
|
对象迭代 |
通过
items()方法将对象转为
|
嵌套使用 |
|
转义
如果您希望特殊字符串(例如
{{
)不被内容模板解析和渲染,可对特殊字符串进行转义。例如:根据如下配置表示保留
{% raw %}
和
{% endraw %}
之间所有的内容。
-
内容模板配置
{% raw %} {% for result in alert.results %} {{ result }} {% endfor %} {% endraw %}
-
结果
{% for result in alert.results %} {{ result }} {% endfor %}
函数
内置模板函数便于您对数据进行各种操作,丰富了通知内容的格式和展示样式。更多信息,请参见 内置模板函数 。
例如您要通过 Webhook 方式发送 JSON 格式的内容,相关信息如下:
-
告警的查询语句(包含一个换行)
* | select count(*) as cnt
-
不同使用方式的对比说明
对比项
内容模板
结果
说明
不使用函数
{ "query": "{{ alert.results[0].query }}" "query": "* | select count(*) as pv" }
JSON 格式不合法
使用 quote 函数
{ "query": {{ quote(alert.results[0].query) }} "query": "* | \nselect count(*) as pv" }
JSON 格式合法
过滤器
在函数嵌套使用场景中,通知内容的编辑麻烦且不够直观,例如
{{ block(to_list(alert.labels)) }}
,此时您可以使用过滤器功能。过滤器使用竖线(|) 操作符,并支持链式调用,一般格式为
{{ xxx | filiter1 | filter2 | ... }}
。例如
{{ blockquote(to_list(alert.labels)) }}
等同于
{{ alert.labels | to_list | blockquote }}
。
使用过滤器方式时,请先确认目标内置函数是否支持过滤器方式。大部分内置函数都支持过滤器方式的调用。更多信息,请参见 内置模板函数 。
-
如果函数中没有参数,则只能使用函数方式,不支持过滤器方式。
-
当函数中只有一个参数时,推荐使用过滤器方式,即使用
{{ arg | fn }}
。例如{{ abs(-1) }}
等同于{{ -1 | abs }}
。 -
如果函数中有多个参数,且从第二个参数开始有默认值,也可以使用过滤器。如果有多个参数值需要传递,通过过滤器方式并不直观。不建议对多参数的函数使用过滤器方式。
操作符
内容模板表达式中支持如下操作符。操作符的优先级说明请参见 Operator precedence 。
类别 |
操作符 |
说明 |
算数 |
+ |
加法 |
- |
减法 |
|
* |
乘法 |
|
/ |
除法,返回值是一个浮点数。 |
|
// |
除法,返回整数。 |
|
% |
取模 |
|
比较 |
== |
等于 |
!= |
不等于 |
|
> |
大于 |
|
>= |
大于等于 |
|
< |
小于 |
|
<= |
小于等于 |
|
逻辑 |
and |
且操作 |
or |
或操作 |
|
not |
取反 |
|
其它 |
in |
判断是否包含,返回布尔类型的结果。
|
() |
操作组合,例如:{{ a > b and (a > c or b > c) }} |
使用告警变量
在新版内容模板中,告警变量的使用形式为
alert.xxx
,例如
alert.project
。更多信息,请参见
内容模板变量说明(新版)
。
配置示例
-
示例 1:根据告警状态展示不同内容
触发告警后,展示告警状态、告警严重度和触发结果等信息;告警恢复时,只展示告警状态。
-
不使用函数
{% if alert.status == "firing" %} - 状态: <font color="#E03C39">触发</font> - 严重度:{{ alert.severity | format_severity }} - Results: {{ alert.results | to_json }} {% else %} - 状态: <font color="#72C140">恢复</font> {% endif %}
-
使用函数
使用 format_status 函数和 format_severity 函数简化配置。
- 状态: {{ alert.status | format_status }} {% if alert.status == "firing" %} - 严重度:{{ alert.severity | format_severity }} - Results: {{ alert.results | to_json }} {% endif %}
-
-
结构化数据展示
将告警标签的内容转换为列表形式,内容为 Markdown 格式。
-
不使用函数
- 项目: {{ alert.project }} - 告警名称: {{ alert.alert_name }} - 告警标签: {%- for key, val in alert.labels.items() %} > - {{ key }}: {{ val }} {%- endfor %}
-
使用函数
使用 to_list 函数和 blockquote 函数简化配置。
- 项目: {{ alert.project }} - 告警名称: {{ alert.alert_name }} - 告警标签: {{ alert.labels | to_list | blockquote }}
-