SLS告警最佳实践——在通知中引用日志内容

概述

在配置告警通知的时候,通常我们需要知道告警的触发详情。例如Nginx访问错误告警,我们需要知道错误的HTTP Status 分布,错误的机器IP等信息,并且需要将这些信息体现在通知中,以便在接收到告警通知后,能够一目了然地知道发生了什么事情。

SLS告警最佳实践——在通知中引用日志内容

那么在创建告警规则的时候,我们就需要进行合理的配置,使得告警在触发后,可以将这些信息放在合适的位置发送给通知服务,从而在通知模板里可以被引用到,从而被正确地通知。

基本属性介绍

在告警规则触发告警后,我们可以通过如下一些属性获取到告警的原始日志信息,它们分别是:

  • labels
  • annotations
  • results
  • fire_results

它们的基本格式以及如何在模板中引用可以参考 内容模板变量说明(新版)。下面来分别进行介绍。

labels

自定义标签

在配置告警规则的时候,我们可以手动添加标签,例如:

SLS告警最佳实践——在通知中引用日志内容

那么在告警触发后,告警消息里就会包含如下信息:

{
    "labels": {
        "app": "nginx",
        "env": "prod"
    }
}

因此在内容模板里,就可以通过如下方式引用标签字段,例如:

应用: {{ alert.labels.app }}
环境: {{ alert.labels.env }}

分组评估

如果设置了分组评估,那么分组评估的字段会默认添加到标签中。关于分组评估的介绍,可以参考文档 分组评估。例如下面的配置,根据 status 字段做分组评估,那么当有错误时,不同的错误码是不同的告警,例如 400 的错误会是一个告警,404 的错误会是另外一个告警,等等。

SLS告警最佳实践——在通知中引用日志内容

此时除了自定义的 app 和 env 标签,还会有一个系统加上去的 stauts 标签。例如 404 的错误触发的告警会包含如下信息:

{
    "labels": {
        "app": "nginx",
        "env": "prod",
        "status": "404"
    }
}

因此在内容模板里,就可以通过如下方式引用标签字段,例如:

应用: {{ alert.labels.app }}
环境: {{ alert.labels.env }}
错误码: {{ alert.labels.status }}

特别注意:

在设置分组评估的时候,需要特别注意,应当使用可枚举的字段。例如 http_status,slb_id 等。而对于不可枚举的随机字段,则不应该作为分组字段,例如 request_time,uuid 等。

annotations

自定义标注

在配置告警规则的时候,我们可以添加标注。与标签相比,标注更加灵活。标注不仅可以配置为固定的文本,还可以引用日志的字段,例如下面配置:

SLS告警最佳实践——在通知中引用日志内容

这里需要注意,默认有两个标注:

  • 标题,即 title 属性
  • 描述,即 desc 属性

那么在告警触发后,告警消息里就会包含如下信息:

{
    "annotations": {
        "title": "Nginx访问错误告警触发",
        "desc": "状态码400错误发生了15次"
    }
}

因此在内容模板里,就可以通过如下方式引用标注字段,例如:

告警标题: {{ alert.annotations.title }}
告警描述: {{ alert.annotations.desc }}

自动添加标注

除了自定义标注,还可以使用自动添加标注功能,例如:

SLS告警最佳实践——在通知中引用日志内容

它本质上相当于:

SLS告警最佳实践——在通知中引用日志内容

fire_results

fire_results 表示的是满足条件的告警记录。例如告警查询语句的结果如下:

SLS告警最佳实践——在通知中引用日志内容当告警规则中触发条件配置为 cnt > 0 的时候:

SLS告警最佳实践——在通知中引用日志内容

触发的告警会有如下属性:

{
    "fire_results": [
        { "status": "401", "ip": "127.0.0.1", "cnt": "3" },
        { "status": "400", "ip": "127.0.0.1", "cnt": "7" },
        { "status": "501", "ip": "127.0.0.1", "cnt": "4" },
        { "status": "404", "ip": "127.0.0.1", "cnt": "4" },
        { "status": "402", "ip": "127.0.0.1", "cnt": "6" },
        { "status": "403", "ip": "127.0.0.1", "cnt": "8" }
    ]
}

当告警规则中触发条件配置为 cnt > 5 时:

SLS告警最佳实践——在通知中引用日志内容

触发的告警的 fire_results 如下:

{
    "fire_results": [
        { "status": "400", "ip": "127.0.0.1", "cnt": "7" },
        { "status": "402", "ip": "127.0.0.1", "cnt": "6" },
        { "status": "403", "ip": "127.0.0.1", "cnt": "8" }
    ]
}

然后就可以在模板变量中引用 fire_results 字段,例如:

告警触发详情: {{ alert.fire_results | to_json }}

results

results 是告警查询最原始的数据,例如上面的例子,告警触发后 results 信息如下:

{
    "results": [{
        "store_type": "log",
        "region": "cn-hangzhou",
        "project": "test-alert",
        "store": "nginx-access-log",
        "query": "status >= 400 | select status, __source__ as ip, count(*) as cnt group by status, ip",
        "start_time": 1640006894,
        "end_time": 1640007014,
        "dashboard_id": "",
        "raw_results": [
            { "status": "401", "ip": "127.0.0.1", "cnt": "3" },
            { "status": "400", "ip": "127.0.0.1", "cnt": "7" },
            { "status": "501", "ip": "127.0.0.1", "cnt": "4" },
            { "status": "404", "ip": "127.0.0.1", "cnt": "4" },
            { "status": "402", "ip": "127.0.0.1", "cnt": "6" },
            { "status": "403", "ip": "127.0.0.1", "cnt": "8" }
        ],
        "raw_result_count": 6,
        "fire_result": {
            "status": "401",
            "ip": "127.0.0.1",
            "cnt": "3"
        },
        "has_sql": true,
        "truncated": false,
        "role_arn": ""
    }]
}

之后也可以通过如下方式来引用原始日志:

告警查询详情: {{ alert.results[0].raw_results | to_json }}

注意:

  • 如果一个告警规则有多个查询语句,那么 results 数组就会有多项,每一项对应一个查询语句。
  • results 表示的是查询语句的原始查询数据,fire_results 表示的是满足告警触发条件的数据,这两者可能会有所差别的。例如触发条件是满足 cnt > 5,那么 results[0].raw_results 结果可能是 6条,但是 fire_results 结果可能是 3条,因为只有3条记录满足 cnt > 5

模板变量引用

循环展示触发日志

上文中 {{ alert.fire_results | to_json }} 会将 fire_results 以 JSON 字符串的形式来进行展示。有时候为了展示更友好,我们会希望通过循环的方式,一行行展示触发日志,此时可以通过循环来实现,例如:

{%- for result in alert.fire_results %}
- status: {{ alert.status }}, count: {{ alert.cnt }}
{%- endfor %}

更多相关信息,可以参考 内容模板语法(新版)

通过模板函数进行数据处理

如果需要对告警的字段进行一些格式化或者处理后再展示,可以通过内置函数来实现。具体可以参考:

上一篇:手写一套迷你版HTTP服务器


下一篇:SLS新版本告警入门——告警策略-路由合并(1)