SLS告警重磅更新——让你的告警通知一目了然

本文涉及的产品
对象存储 OSS,20GB 3个月
对象存储 OSS,恶意文件检测 1000次 1年
对象存储 OSS,内容安全 1000次 1年
简介: SLS告警最近升级了通知的模板语法,在保持对原有模板语法兼容的情况下,增加了动态渲染的功能,不仅支持条件语句、循环语句等控制流,还内置了50+函数,可以非常方便地对数据进行各种处理,从而可以非常灵活方便地对通知内容进行定制,让通知内容呈现的效果更加丰富、内容一目了然。

前言

SLS告警最近升级了通知的模板语法,在保持对原有模板语法兼容的情况下,增加了动态渲染的功能,不仅支持条件语句、循环语句等控制流,还内置了50+函数,可以非常方便地对数据进行各种处理,从而可以非常灵活方便地对通知内容进行定制,让通知内容呈现的效果更加丰富、内容一目了然。


旧模板语法回顾

在配置告警通知的时候,我们需要配置通知的内容模板,例如下面的一个钉钉通知模板:

- 所属项目: ${project}
- 告警名称: ${alert_name}
- 首次触发: ${fire_time}
- 告警时间: ${alert_time}
- 告警状态: ${status}
- 告警严重度: ${severity}
- 告警标签: ${labels}
- 告警标注: ${annotations}
- 触发日志: ${fire_results}

假如告警内容为:

{
"project": "test-project",
"alert_id": "nginx-error",
"alert_name": "Nginx访问错误",
"fire_time": 1632802350,
"alert_time": 1632802351,
"resolve_time": 0,
"status": "firing",
"severity": 10,
"labels": {
"service": "nginx",
"region": "cn-hangzhou" },
"annotations": {
"title": "Nginx访问错误",
"desc": "Nginx最近1分钟内有96条错误日志" },
"fire_results": [{
"msg": "ERROR: Internal Server Error"  }, {
"msg": "ERROR: uri /foo/bar not exist"  }]
}

则渲染后的通知内容为:

- 所属项目: test-project
- 告警名称: Nginx访问错误
- 首次触发: 2021-09-28 12:12:30
- 告警时间: 2021-09-28 12:12:31
- 告警状态: 触发
- 告警严重度: 严重
- 告警标签: {"service": "nginx", "region": "cn-hangzhou"}
- 告警标注: {"title": "Nginx访问错误", "desc": "Nginx最近1分钟内有96条错误日志"}
- 触发日志: [{"msg": "ERROR: Internal Server Error"}, {"msg": "ERROR: uri /foo/bar not exist"}]

这里模板的渲染逻辑比较简单,可以简单理解为近似于变量直接替换。通过上面的例子我们可以发现旧的模板语法存在的几个问题:

  1. 逻辑处理能力缺失,无法做到动态渲染
  • 例如希望根据告警状态来进行动态渲染:告警触发是展示触发日志,告警恢复时无需展示触发日志
  • 例如希望遍历 fire_results,将错误日志以列表形式展示
  1. 数据处理能力弱
  • 例如希望将触发日志里的 ERROR 前缀去掉
  • 例如希望告警触发时间展示为其它格式
  1. 内容与样式耦合
  • 告警的时间、状态、严重度等属性,都是根据当前的语言环境自动进行了格式化(例如时间由时间戳转成了“2021-09-28 12:12:30”;告警状态由“firing” 转成了“触发”;严重度由数字10自动转成了“严重”)
  • 如果希望根据原始属性值,自定义展示形式,则无法做到

这些能力的缺失,一方面会导致最终的通知展示不够友好,另一方面,也会导致某些场景无法支持。例如Webhook通知渠道的模板配置为JSON格式:

{
  "msg": "${fire_results[0].msg}"
}

假如实际告警的触发日志中,包含了换行符或者双引号,则上面的模板渲染后就不是一个合法的JSON。例如原始 msg 内容为:

Uncaught Error: unexpected error
    at <anonymous>:1:7

则渲染后的内容为:

{
  "msg": "Uncaught Error: unexpected error
    at <anonymous>:1:7"
}

由于渲染后的结果不是合法JSON,因此就会导致告警通知发送失败。


新模板语法

为了解决上述痛点,我们重新设计了告警通知的内容模板语法,不仅可以解决上述问题,而且内置了非常多的数据处理函数,可以按需来对原始的告警内容进行处理,从而达到自己想要的通知效果。新旧版本的告警通知模板语法比较如下:


新版通知模板语法

旧版通知模板语法

变量引用

通过 {{ alert.xxx }} 来引用告警的属性,例如 {{ alert.project }}(其中大括号的空格不是必须,这里只是为了格式好看)

通过 ${xxx} 来引用告警的属性,例如 ${project}

操作符

支持常用的算数操作和逻辑操作,包括:

  • 加减乘除四则运算
  • and,or,not 逻辑运算
  • 大小比较运算
  • 取模计算

不支持

条件判断

支持

不支持

循环语句

支持

不支持

数据处理函数

内置了50+函数用于数据的处理和格式化,包括:

  • 数学计算函数
  • 字符串处理函数
  • 日期函数
  • 编解码函数
  • 等等

不支持


针对上面的例子,我们使用新版本的模板语法,可以配置通知模板如下:

- 所属项目: {{ alert.project }}
- 告警名称: {{ alert.alert_name }}
- 首次触发: {{ alert.fire_time | format_date }}
- 告警时间: {{ alert.alert_time | format_date }}
- 告警状态: {{ alert.status | format_status }}
- 告警严重度: {{ alert.severity | format_severity }}
- 告警标签:
{%- for key, value in alert.labels.items() %}
 - {{ key }}: {{ value }}
{%- endfor %}
- 告警标注:
{%- for key, value in alert.annotations.items() %}
 - {{ key }}: {{ value }}
{%- endfor %}
- 触发日志:
{% for result in alert.fire_results %}
 - {{ result.msg }}
{% endfor %}

则最终渲染后的内容为:

- 所属项目: test-project
- 告警名称: Nginx访问错误
- 首次触发: 2021-09-28 12:12:30
- 告警时间: 2021-09-28 12:12:31
- 告警状态: 触发
- 告警严重度: 严重
- 告警标签:
 - service: nginx
  - region: cn-hangzhou
- 告警标注:
  - title: Nginx访问错误
  - desc: Nginx最近1分钟内有96条错误日志
- 触发日志:
 - ERROR: Internal Server Error
  - ERROR: uri /foo/bar not exist


案例

案例一:格式化钉钉通知内容

旧版模板

新版模板

模板配置

- 所在项目: ${project}
- 告警名称: ${alert_name}
- 触发时间: ${fire_time}
- 告警状态: ${status}
- 严重度: ${severity}
- 标签: ${labels}
- 标注: ${annotations}

[[查看详情](${query_url})]
[[告警设置](${alert_url})]
- 所在项目: {{ alert.project }}
- 告警名称: {{ alert.alert_name }}
- 触发时间: {{ alert.fire_time | format_date }}
- 告警状态: {{ alert.status | format_status }}
- 严重度: {{ alert.severity | format_severity }}
- 标签:
{{ alert.labels | to_list | blockquote }}
- 标注:
{{ alert.annotations | annotations_to_list | blockquote }}

[[查看详情]({{ alert.query_url }})]
[[告警设置]({{ alert.alert_url }})]

展示效果

image.png

image.png

这里我们使用了如下内置函数:

函数处理

作用

{{ alert.fire_time | format_date }}

format_date 用来对时间进行格式化,默认格式化微 yyyy-MM-dd HH:mm:ss 格式

{{ alert.status | format_status }}

format_status 用来对告警状态进行格式化:

  • 根据当前语言环境展示不同的语言内容,例如 "firing" 会展示为 "触发" 或 "Firing"
  • 根据触发或者恢复状态,展示不同颜色的字体(针对钉钉、企业微信、邮件等富文本渠道有效)

{{ alert.severity | format_severity }}

format_severity 用来对告警严重度进行格式化,类似于 format_status:

  • 根据当前语言环境展示不同的语言内容,例如严重度为 10 会展示位 "严重" 或 "Critical"
  • 根据告警严重度,展示不同颜色的字体(针对钉钉、企业微信、邮件等富文本渠道有效)

{{ alert.labels | to_list | blockquote }}

  • to_list 将告警标签转化为列表形式(在钉钉渠道下是 Markdown 形式列表,在邮件渠道下是 HTML <ul> 标签)
  • blockquote 将内容转化为引用格式(在钉钉下是 > xxx 语法,在邮件渠道下是 <blockquote>xxxx</blockquote> 形式)

{{ alert.annotations | annotations_to_list | blockquote }}

annotations_to_list 功能与 to_list 非常类似,只不过会额外将一些字段进行翻译,例如 title 会根据语言环境展示为 "标题" 或 "Title"


使用内置的格式化函数有如下优点:

  • 开箱即用:默认对告警状态、严重度等属性,以及列表、引用等常见格式做了包装。
  • 屏蔽了不同渠道的差异:不同的通知渠道对格式的支持是有区别的,例如钉钉支持彩色字体,但是有些渠道可能就不执行。另外同样都是列表展示,在钉钉下是 Markdown 格式,在邮件下是 HTML 格式。内置的函数对此进行了封装,屏蔽了不同渠道的差异,对外提供出来的是一套统一的语法,从而方便使用。


案例二:Webhook JSON 内容配置

在使用 Webhook 通知渠道的时候,通常我们都会使用 JSON 格式的内容。

旧版模板

新版模板

模板配置

{
  "project": "${project}",
  "alert_name": "${alert_name}",
  "fire_time": ${fire_time},
  "status": "${status}",
  "severity": "${severity}",
  "labels": ${labels},
  "annotations": ${annotations}
}
{
  "project": "{{ alert.project }}",
  "alert_name": "{{ alert.alert_name }}",
  "fire_time": {{ alert.fire_time }},
  "status": {{ alert.status | format_status | quote }},
  "severity": {{ alert.severity | format_severity | quote }},
  "labels": {{ alert.labels | to_json }},
  "annotations": {{ alert.annotations | to_json }}
}

这里新版模板使用了如下函数:

函数处理

作用

{{ alert.status | format_status | quote }}

{{ alert.status | format_status | quote }}"{{ alert.status | format_status }}" 作用相同,但是使用 quote 的好处是,如果需要引用的内容里本身包含了双引号或者换行等字符,那么就会导致字符串不合法,最终导致 JSON 格式错误,而使用 quote 函数处理就可以避免该问题。

{{ alert.labels | to_json }}

to_json 用于将数据转为 JSON 格式,这里我们可以非常明显地看到告警标签是以 JSON 格式来进行展示的。

这里我们可以看到新版模板语法的一个显著特点,即内容与样式分离,例如通过 quote 可以显式的看出渲染后是一个字符串,通过 to_json 可以显式的看到是一个 JSON 格式。通过内容与样式分离,可以通过内置的函数来自定义需要的展示样式,从而更加灵活。

案例三:动态渲染

例如原始数据如下:

image.png

希望将错误的 host 和 remote_uri 遍历展示出来,可以配置内容模板如下:

- 所在项目: {{ alert.project }}
- 告警名称: {{ alert.alert_name }}
- 触发时间: {{ alert.fire_time | format_date }}
- 告警状态: {{ alert.status | format_status }}
- 严重度: {{ alert.severity | format_severity }}
- 标签:
{{ alert.labels | to_list | blockquote }}
- 触发详情:
{%- if alert.status == 'firing' %}
{%- for result in alert.fire_results %}
    - {{ result.host }}{{ result.request_uri }}
{%- endfor %}
{%- endif %}
[[查看详情]({{ alert.query_url }})]
[[告警设置]({{ alert.alert_url }})]

通知效果如下:

image.png

这里我们通过 if 条件判断和 for 循环结合,从而可以在告警是触发状态的时候,遍历渲染出所有的触发数据。


进一步参考

更多相关信息,可以参考:

对我们工作感兴趣的,可以通过如下方式了解更多,谢谢关注!

image.png

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
消息中间件 存储 运维
Zabbix与ELK整合实现对安全日志数据的实时监控告警
Zabbix与ELK整合实现对安全日志数据的实时监控告警
Zabbix与ELK整合实现对安全日志数据的实时监控告警
|
2月前
|
JSON Prometheus Cloud Native
Grafana 系列 -Loki- 基于日志实现告警
Grafana 系列 -Loki- 基于日志实现告警
|
7月前
|
Web App开发 存储 监控
日志服务之告警接入与管理
本教程介绍如何使用日志服务接入NGINX模拟数据,并配置告警规则来对NGINX访问错误进行监控。
333 0
|
5月前
|
监控 数据库
136 日志监控告警系统案例(代码实现)
136 日志监控告警系统案例(代码实现)
82 0
|
5月前
|
监控
135 日志监控告警系统案例(数据模型设计)
135 日志监控告警系统案例(数据模型设计)
77 0
|
5月前
|
消息中间件 监控 关系型数据库
134 日志监控告警系统案例(功能架构分析)
134 日志监控告警系统案例(功能架构分析)
70 0
|
Oracle 关系型数据库
Oracle自带adrci工具清理告警日志
Oracle自带adrci工具清理告警日志
510 0
Oracle自带adrci工具清理告警日志
|
SQL 监控 关系型数据库
【python小脚本】监听日志文件异常数据发送告警短信
老项目中有个用脚本启动的服务,很重要,用来做业务留痕的,涉及业务客户经常性投诉,是找第三方做的,时间长了维护需要花钱,老出各种未知bug,没办法处理所以机器上配了定时任务,定期的几天重启一次来解决。 但是有时候不知道什么原因,重启脚本运行,服务没起来,crond 也没有什么调度机制。 希望写个脚本做监控,当发现服务没起来,发送告警信息,或者重启服务。
139 0
|
监控
限制SLS告警通知时段的几种常见方法
在对系统进行监控告警的过程中,有时候并非在任何时候都要接收告警通知,本文会介绍几种常见的限制告警通知时段的方法,以及它们各自所适用的场景。
348 0
限制SLS告警通知时段的几种常见方法
|
机器人 定位技术
GrayLog+nxlog采集邮箱登录日志csv文件并实现邮箱异地登录钉钉机器人告警
GrayLog+nxlog采集邮箱登录日志csv文件并实现邮箱异地登录钉钉机器人告警
261 0
GrayLog+nxlog采集邮箱登录日志csv文件并实现邮箱异地登录钉钉机器人告警

相关产品

  • 日志服务