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

本文涉及的产品
对象存储 OSS,20GB 3个月
阿里云盘企业版 CDE,企业版用户数5人 500GB空间
日志服务 SLS,月写入数据量 50GB 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日志并进行多维度分析。
目录
相关文章
|
5月前
|
运维 Serverless API
Serverless 应用引擎产品使用合集之sls日志告警调用函数计算,出现抛出的结果异常,是什么原因
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
5月前
|
存储 运维 Serverless
函数计算产品使用问题之日志告警不生效,一般是由于什么造成的
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
Web App开发 存储 监控
日志服务之告警接入与管理
本教程介绍如何使用日志服务接入NGINX模拟数据,并配置告警规则来对NGINX访问错误进行监控。
406 0
|
6月前
|
JSON Prometheus Cloud Native
Grafana 系列 -Loki- 基于日志实现告警
Grafana 系列 -Loki- 基于日志实现告警
|
监控 数据库
136 日志监控告警系统案例(代码实现)
136 日志监控告警系统案例(代码实现)
115 0
|
监控
135 日志监控告警系统案例(数据模型设计)
135 日志监控告警系统案例(数据模型设计)
158 0
|
消息中间件 监控 关系型数据库
134 日志监控告警系统案例(功能架构分析)
134 日志监控告警系统案例(功能架构分析)
141 0
|
分布式计算 监控 前端开发
133 日志监控告警系统案例(需求分析)
133 日志监控告警系统案例(需求分析)
101 0
|
6月前
|
机器学习/深度学习 运维 监控
用SLS配置日志关键字告警的N种方法
本文由日志关键词告警出发,介绍了使用SLS进行关键词监控告警配置,并且介绍了几种常见的配置方法,可以覆盖关键词监控的大部分场景。
349 0
用SLS配置日志关键字告警的N种方法
|
6月前
|
存储 运维 监控
使用Terraform玩转SLS告警
本文主要介绍使用Terraform来操作SLS告警监控,告警管理。
104 0
使用Terraform玩转SLS告警

相关产品

  • 日志服务