本篇博客介绍了 AlertManager
报警收敛的若干种方法。
背景
当一个监控-告警系统建立起来后,告警系统将会面临这样的问题:警报消息太多,接收人很容易麻木,不再继续理会,关键的告警常常被淹没。
对于这一问题,AlertManger
提供了非常好的解决方案。Prometheus
把一条告警信息发送给了 AlterManager
,AlterManager
并不是简简单单地直接发送出去,而是对告警信息进行了一些诸如分组、延时等收敛处理。
对报警收敛的支持,AlertManager
提供了以下四种方式:
- 分组
- 抑制
- 静默
- 延时
告警分组
告警分组是通过对具有相同属性值的告警进行分组聚合,可以有效的减少告警消息的数量。
对应 AlertManager
的配置,通过 route
部分的 group_by
字段对具有相同属性的告警进行分组聚合。
|
|
告警抑制
当告警发出后,停止重复发送由此告警引发的其他告警。一般是由更高级别的告警抑制低级别的告警。这可以消除冗余的告警,仅发送关键警报,避免误导运维排查问题的方向。
在 AlertManager
的配置中,通过 inhibit_rules
部分来配置
|
|
以上配置告诉 AlertManager
,对于具有相同 alertname
的告警,含 severity: 'critical'
标签的告警将会抑制含 severity: 'warning'
标签的告警。
告警静默
对可预期的告警,在特定时间段阻止告警的发送,比如,线上环境资源调整或上线,可能会导致告警,此时,可以增加告警静默,阻止相关的告警发送。
可以在 http://localhost:9093/#/silences
中进行创建。
告警延时
当故障发生时,若故障未能及时解决,频繁地发送告警是令人崩溃的。group_wait
把开始产生的告警收集起来,最后作为一条告警信息发送出来,repeat_interval
可以将重复的告警以更大的时间间隔发送。
在 AlertManager
的配置中进行如下配置:
|
|
其他方式
我们也可以考虑把告警信息都收集起来,做统计分析,基于统计数据按周、月生成告警报告,比如,哪些应用在哪段时间里产生了最多的报警,哪些指标在哪段时间里产生了最多的报警,某个报警阈值的 90% 分位数、95%分位数、99%分位数,哪个部门产生了最多的报警数等等。一来要求业务团队改造程序或结构,调整资源配置,比如有些代码写得性能特别差,资源占用高,导致告警信息频繁发送;二来可以作为我们设置各种资源阈值的统计参考数据,取代常用的经验值或习惯值,比如,根据历史报警数据的统计,采取百分位数,使得某告警在 95%
的情况下不再发送告警信息。
总结和思考
做好告警的收敛是很有必要的,也有多种方法。借助于 AlertManager
,我们可以通过分组、抑制、静默和延时等方法来做告警的收敛。
就 AlertManager
而言,在告警抑制上,我们还可以考虑更多的告警抑制规则,比如,在多种告警级别(critical
、emergency
、warning
等)的情况下,每一种高级别告警抑制所有比它低的级别的告警;在告警延时上,高级别告警的延时参数缩短,低级别告警的延时参数增长。
另外,基于统计数据按周、月生成告警报告,改进应用程序和架构,合理设置阈值,更好和更准确地报警。
考虑这样一种设计,我们想把 AlertManager
发送的报警收集起来,那么,由于 AlertManager
会把从 Prometheus
发送来的报警信息进行分组聚合,抑制等操作,从而导致实际产生的报警一般会多于发送出来的报警。如果我们想把 AlertManager
的报警信息收集起来,那么,我们是应该在 AlertManager
接收到报警的时候收集,还是在真正发送报警之前进行收集?
如果是在接收到报警时收集,那么我们实际上会收集到所有产生的报警,数据量大,信息详尽。如果使用这些进行分析,进而改进代码、程序架构和资源配置,那么,将会从上游彻底地减少报警,并且促进整个研发运维的进步和系统的稳定性。
如果是在实际发送时收集,那么我们收集到的数据量就会比较小,报警是经过聚合的,被抑制的报警不发送,经过分析优化后,将会使得接收到的报警数量减少,但是产生的报警(按原来的标准,这种情况下会产生报警)却可能增多,比如在不做上游改变的情况下,调整阈值,使得 99%
的报警不发送,问题则会堆积在 Prometheus
那边,不会向 AlertManager
发送报警。
根据以上分析,我们选择在 AlertManager
接收到报警时即收集之。