· 更多精彩内容,请下载阅读全本《Elastic Stack实战手册》
创作人:金端/扈臣聪
审稿人:周海清
Kibana 的 Alert 模块主要用于 Elastic Stack 的监控告警。以一种相对较低的使用成本,将复杂的查询条件,编辑完成后监控不同的 Elastic Stack 的技术产品中产生的数据,最终把符合条件的告警信息以需要的方式反馈给用户。
Alert 的组成
Alert 主要由三个部分组成:
Condition 条件
也是 Alert Type,检测需要执行的查询或者统计。
Condition 的概念执行主要由 alert type 承担。Alert Type 通过简单的参数设置将涉及 Elasticsearch 的查询结果和其它数据源的复杂计算完美实现。比如:监控的程序 APM 数据2分钟内 CPU 使用均值高于0.9;某个业务数据索引中,10分钟内购买失败次数占比超总量的30%等等.
Schedule 检测周期
Alert 的执行周期。Schedule 的设置按照每隔多久循环来设置,从每秒到每月不等,但并不能设置具体哪月哪天。
Action 告警动作
即满足告警条件后需要执行的操作,主要是将需要的告警信息发送给第三方系统,在 Kibana 后台执行。
Action 可以分解为三个要素:
- action type,发送的第三方系统类型定义。
- connection,告警发送的连接信息,比如email的host和端口等
- properties,告警信息所需要引用的参数值。
Alert 与 Elasticsearch 的 Watcher不同的是,Alert 运行在 Kibana 而不是 Elasticsearch,相关任务数据也是存储在 Kibana 的索引中,而 Elasticsearch 的 Watcher 数据则是在 Watcher 的索引中。
在更高的层次上,Kibana Alert 允许跨用例(如 APM、Metrics、Scurity 和 Uptime)进行丰富的集成。预先打包的 Alert Type 简化了设置,隐藏了复杂的检测细节,同时提供了跨 Kibana 的一致接口。
Alert Instances 的概念和抑制重复告警
在检查一个 condition 条件时,Alert 可能会识别该条件的多次出现。每出现一次符合 condition 条件的情况,Kibana 就生成一个 Alert Instances,即警报实例。那么 Kibana 分别跟踪每个警报实例,并对每个实例采取行动。
重复告警
以下面的图示例,将每个平均 CPU 为> 0.9 的服务器作为 Alert Instance 进行跟踪。然后将每个超过阈值的服务器都将发送单独的电子邮件。
那就会带来一个问题,当 Alert Instances 过多的时候,就会造成大量通知重复发送,即 Alert Noise 的现象。
比如一个警报每分钟监控三个服务器的 CPU 使用情况> 0.9,就发送邮件通知工作人员:
- 第一分钟:服务器 X123 的 CPU > 0.9。
其中一封邮件发送通知工作人员服务器 X123 的 CPU 过高。
- 第二分钟:X123 和 Y456 的 CPU > 0.9。
发送了两封邮件,一封是关于 X123 的,一封是关于Y456的。
- 第三分钟:X123, Y456, Z789 的 CPU > 0.9。
发送了三封邮件,分别是 X123,Y456,Z789。
在上面的例子中,对于相同的条件,在3分钟的时间内,向服务器 X123 发送了3封邮件。
抑制重复告警
Kibana 针对这个情况做了抑制重复通知的优化,主要是通过设置通知间隔来抑制重复多余的告警。比如在上面的例子中,将警报重新通知间隔设置为5分钟,那么 Alert 发送通知的情况则如下:
- 第一分钟:服务器 X123 > 0.9
邮件发送报告服务器 X123 的 CPU 过高;
- 第二分钟:X123 和 Y456 > 0.9
邮件发送报告服务器 Y456 的 CPU 过高;
- 第三分钟:X123, Y456, Z789 > 0.9
邮件发送报告服务器 Z789 的 CPU 过高。
当然过了五分钟后,如果服务器 X123 > 0.9还是存在,那么继续会发送邮件,报告服务器 X123 的 CPU 过高。
Kibana Alert 的实现机制
Kibana Alert 将 Alert Check 的信息和 Action 的信息,持久化在 Elasticsearch 在后台执行。这有两个主要好处:
- 持久性:所有的任务相关的信息都存储在 Elasticsearch 中,所以如果 Kibana 重新启动,Alert 和 Action 将从它们停止的地方恢复;
- 伸缩性:多个 Kibana 实例可以从 Elasticsearch 中读取和更新相同的任务队列,允许 Alert 和 Action 跨实例分布。如果现有的 Alert 执行数量超出了现有的 Kibana 实例的容量上限,可以增加额外的 Kibana 实例。
Kibana 后台任务的执行机制
- 每隔3秒轮循 Elasticsearch 任务索引以查找过期任务;
- 任务执行后在 Elasticsearch 索引中更新,使用乐观并发控制来防止冲突;
- 任务在 Kibana 服务器上运行。每个 Kibana 实例最多可以运行 10 个并发任务,因此每个间隔最多可以声明 10 个任务;
- 对于重复后台检查的 Alert,任务完成后将按照检查间隔再次调度。
因为每3秒轮询一次任务,并且每个 Kibana 实例只能同时运行10个任务,所以 Alert 和 Action 任务可能会在以下情况延迟运行:
- 警报使用较小的检查间隔。最低间隔时间可能是 3 秒,但建议间隔时间为 30 秒或更高
- 许多警报或操作必须同时运行。在这种情况下,挂起的任务将在 Elasticsearch 中排队,并且每隔 3 秒从队列中取出 10 个任务
- 长时间运行的任务占用槽位的时间较长,留给其他任务的槽位较少
完整的 Alert 流程
Alert 由 Condition(条件)、Action 和 Schedule 组成。当条件满足时,就会创建警报实例来呈现和调用操作。为了使 Action 设置和更新更容易,Action 包含了与第三方连接交互的 Connector 。
下面的例子将这些概念联系在一起:
- 只要警报的条件得到满足,就会创建一个警报实例。这个示例检查平均 CPU 为 > 0.9 的服务器。三个服务器满足条件,因此创建了三个实例;
- Action 执行时,警报中设置的模板将被实际值填充。在这个示例中,创建了三个操作,模板字符串 {{server}} 被替换为每个实例的服务器名;
- Kibana 调用这些 Action,将它们发送给第三方集成,比如邮件服务;
- 发送这些信息时,Action 会结合 Connector 中设置的信息发送。比如:邮件的 host/port/用户名/密码。
如何配置 Alert
目前 Kibana 提供了一种内置的警报类型:索引阈值类型(index threshold)。索引阈值警报类型,允许您指定要查询的索引、聚合字段和时间窗口。但底层 Elasticsearch 查询的详细信息是隐藏的。根据设定的查询条件,将结果与阈值进行比较,并在满足阈值时进行后续的调度执行。
操作示范
在 Stack management 的 Alert 中 Create alert,新建一个名为 test-alert 的告警。该告警用于检查索引test-es中fail_num的累计数量,test-alert每分钟检查一次,最多5分钟告警通知一次,标签为test。
索引test-es的数据如下:
PUT test-es
POST test-es/_mapping
{
"properties" : {
"@timestamp" : {
"type" : "date",
"format" : "yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis"
},
"fail_num" : {
"type" : "long"
},
"user" : {
"properties" : {
"id" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
POST _bulk
{ "create" : { "_index" : "test-es", "_id" : "1" } }
{ "@timestamp" : "2021/04/20 23:30:30" ,"user.id":"may","fail_num":"1"}
{ "create" : { "_index" : "test-es", "_id" : "2" } }
{ "@timestamp" : "2021/04/20 23:33:31" ,"user.id":"may","fail_num":"4"}
{ "create" : { "_index" : "test-es", "_id" : "4" } }
{ "@timestamp" : "2021/04/20 23:46:30" ,"user.id":"jack","fail_num":"1"}
{ "create" : { "_index" : "test-es", "_id" : "5" } }
{ "@timestamp" : "2021/04/20 23:50:30" ,"user.id":"may","fail_num":"6"}
{ "create" : { "_index" : "test-es", "_id" : "6" } }
{ "@timestamp" : "2021/04/20 23:49:30" ,"user.id":"jack","fail_num":"3"}
{ "create" : { "_index" : "test-es", "_id" : "7" } }
{ "@timestamp" : "2021/04/20 23:49:30" ,"user.id":"jack","fail_num":"3"}
{ "create" : { "_index" : "test-es", "_id" : "8" } }
{ "@timestamp" : "2021/04/20 23:50:30" ,"user.id":"bill","fail_num":"9"}
{ "create" : { "_index" : "test-es", "_id" : "9" } }
{ "@timestamp" : "2021/04/20 23:52:30" ,"user.id":"jack","fail_num":"1"}
{ "create" : { "_index" : "test-es", "_id" : "10" } }
{ "@timestamp" : "2021/04/20 23:53:30" ,"user.id":"jack","fail_num":"1"}
选择 Index threshold
配置 condition 条件为:监控索引 test-es 中10分钟内,如果 fail_num 总计超过5次则告警。
其中,WHEN 条件可选择为 count,average,sum,min 和 max。
count 为统计文档数,不需要填写字段,其余方法会自动匹配出可计算类型的字段,比如 long 类型。
OVER 条件可以配置聚合全部文档或者分组。如果使用了分组,即 top,那么当每个组超过阈值时,将为每个组创建一个 Alert Instance。在配置中,top 会设定分组数量,限制高基数字段上的实例数量。比如上图中只检查 user.id.keyword 数量最多的3组。
相关的查询结果会有一张时序图来体现,如下图:
从图中看出前三个是 may 6次、jack 9次、bill 9次。
再设置一个 Action,此处是写进索引 alert-record
保存后,过段时间 Alert 的详情里就有了 Alert Instance 的相关信息。
其中 Status 为 Active 的是待执行 Action 操作的。不管 Alert Instance 在被监控判断的期间是否被静音( Mute ),最终状态都为 OK。
关于 Actions
预设置 Connector 和 Action
可以在 kibana.yml 中预设值 Connector 或者 Action Type。
预设 Connector 需要将配置和相关证书设置清楚,不可以数组对象的形式设置,且配置完以后不可修改。相比之下在 Kibana 启动后,再设置 Connector 相对灵活许多。
Connector 和 Action 的具体配置可参考官方网站。
Action 的变量传入
在设置 Action 时,根据 Action Type 的不同,会设置不同的 properties。比如,email 配置 Subject 和 Message;Index 提供 document。具体细节参考每个类型的具体 action 配置。
虽然各个 Properties 不一样,但是在配置时都可以把 Alert 中监控到的数据,作为变量传入报警信息中。使用 Mustache 模板语法 {{variable name}},可以在检测到一个 Condition 时将警报值传递给一个 Action。
可用的变量因 Alert Type 不同而不同,可以使用 "Add variable" 按钮来访问列表。
下图是 email 的可传入参数: