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

本文涉及的产品
对象存储 OSS,20GB 3个月
对象存储 OSS,内容安全 1000次 1年
对象存储 OSS,恶意文件检测 1000次 1年
简介: 在配置告警通知的时候,通常我们需要知道告警的触发详情。例如Nginx访问错误告警,我们需要知道错误的HTTP Status 分布,错误的机器IP等信息,并且需要将这些信息体现在通知中,以便在接收到告警通知后,能够一目了然地知道发生了什么事情。那么在创建告警规则的时候,我们就需要进行合理的配置,使得告警在触发后,可以将这些信息放在合适的位置发送给通知服务,从而在通知模板里可以被引用到,从而被正确地通知。

概述

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

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

基本属性介绍

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

  • labels
  • annotations
  • results
  • fire_results

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

labels

自定义标签

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

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

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

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

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

分组评估

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

此时除了自定义的 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

自定义标注

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

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

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

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

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

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

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

自动添加标注

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

它本质上相当于:

fire_results

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

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

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

{
"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 时:

触发的告警的 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 字符串的形式来进行展示。有时候为了展示更友好,我们会希望通过循环的方式,一行行展示触发日志,此时可以通过循环来实现,例如:

{%-forresultinalert.fire_results%}
-status: {{ alert.status }}, count: {{ alert.cnt }}
{%-endfor%}

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

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

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

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
26天前
|
XML JSON Java
Logback 与 log4j2 性能对比:谁才是日志框架的性能王者?
【10月更文挑战第5天】在Java开发中,日志框架是不可或缺的工具,它们帮助我们记录系统运行时的信息、警告和错误,对于开发人员来说至关重要。在众多日志框架中,Logback和log4j2以其卓越的性能和丰富的功能脱颖而出,成为开发者们的首选。本文将深入探讨Logback与log4j2在性能方面的对比,通过详细的分析和实例,帮助大家理解两者之间的性能差异,以便在实际项目中做出更明智的选择。
165 3
|
26天前
|
存储 缓存 关系型数据库
MySQL事务日志-Redo Log工作原理分析
事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。
1602 14
|
12天前
|
XML JSON 监控
告别简陋:Java日志系统的最佳实践
【10月更文挑战第19天】 在Java开发中,`System.out.println()` 是最基本的输出方法,但它在实际项目中往往被认为是不专业和不足够的。本文将探讨为什么在现代Java应用中应该避免使用 `System.out.println()`,并介绍几种更先进的日志解决方案。
34 1
|
22天前
|
Python
log日志学习
【10月更文挑战第9天】 python处理log打印模块log的使用和介绍
20 0
|
2月前
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP的编程实践中,设计模式是解决常见软件设计问题的最佳实践。单例模式作为设计模式中的一种,确保一个类只有一个实例,并提供全局访问点,广泛应用于配置管理、日志记录和测试框架等场景。本文将深入探讨单例模式的原理、实现方式及其在PHP中的应用,帮助开发者更好地理解和运用这一设计模式。
在PHP开发中,单例模式通过确保类仅有一个实例并提供一个全局访问点,有效管理和访问共享资源。本文详细介绍了单例模式的概念、PHP实现方式及应用场景,并通过具体代码示例展示如何在PHP中实现单例模式以及如何在实际项目中正确使用它来优化代码结构和性能。
43 2
|
23天前
|
数据可视化
Tensorboard可视化学习笔记(一):如何可视化通过网页查看log日志
关于如何使用TensorBoard进行数据可视化的教程,包括TensorBoard的安装、配置环境变量、将数据写入TensorBoard、启动TensorBoard以及如何通过网页查看日志文件。
126 0
|
26天前
|
存储 分布式计算 NoSQL
大数据-136 - ClickHouse 集群 表引擎详解1 - 日志、Log、Memory、Merge
大数据-136 - ClickHouse 集群 表引擎详解1 - 日志、Log、Memory、Merge
30 0
|
27天前
|
缓存 Linux 编译器
【C++】CentOS环境搭建-安装log4cplus日志组件包及报错解决方案
通过上述步骤,您应该能够在CentOS环境中成功安装并使用log4cplus日志组件。面对任何安装或使用过程中出现的问题,仔细检查错误信息,对照提供的解决方案进行调整,通常都能找到合适的解决之道。log4cplus的强大功能将为您的项目提供灵活、高效的日志管理方案,助力软件开发与维护。
47 0
|
2月前
|
Java
日志框架log4j打印异常堆栈信息携带traceId,方便接口异常排查
日常项目运行日志,异常栈打印是不带traceId,导致排查问题查找异常栈很麻烦。
|
2月前
|
开发者 Python
基于Python的日志管理与最佳实践
日志是开发和调试过程中的重要工具,然而,如何高效地管理和利用日志常常被忽略。本文通过Python中的logging模块,探讨如何使用日志来进行调试、分析与问题排查,并提出了一些实际应用中的优化建议和最佳实践。

相关产品

  • 日志服务