新版告警支持两个版本的内容模板语法。本文介绍新版内容模板语法。
概述
相对于旧版的内容模板语法,新版通过类似 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 }}
 
- 
             


