告警的路由与分组
告警的标签
Prometheus 发给 alertmanager 的每一条告警信息都是带有标签的,而且 alertmanager 是通过标签来标识每一条告警信息。比如说,下面是 alertmanager 接收到的一系列告警信息
{alertname="NodeCPU",instance="peng01",job="node-exporter",serverity="high",...} time, annotation
{alertname="NodeMemory",instance="peng01",job="node-exporter",serverity="high",...} time, annotation
{alertname="NodeCPU",instance="peng02",job="node-exporter",serverity="high",...} time, annotation
{alertname="NodeMemory",instance="peng02",job="node-exporter",serverity="high",...} time, annotation
...
路由
假设 Prometheus 同时监控了两个组件:数据库组件与缓存组件,希望构建如下的监控流程:
- 数据库组件的告警能够发送给数据库小组的相关人员
- 缓存组件的告警能发送给缓存小组的相关人员
基于告警信息的标签与 alertmanager 的路由机制,可以达到上面的效果
比如,定义如下的路由树:
route:
receiver: admin-receiver
routes:
- receiver: database-receiver
match:
component: database
- receiver: memcache-receiver
macth:
componnet: memcache
那么,当 alertmanager 收到一条告警信息时,首先会发送给 admin-receiver;然后根据标签的匹配规则,如果该告警带有标签 component: database
,就会发送给 database-receiver
如果数据库的告警还要继续细分,比如 mysql 的告警还要发送给 mysql-receiver,marriadb 的告警发送给 marriadb-receiver,那么可以路由树如下:
route:
receiver: admin-receiver
routes:
- receiver: database-receiver
match:
component: database
routes:
- receiver: mysql-receiver
match:
type: mysql
- receiver: marriadb-receiver
match:
type: marriadb
- receiver: memcache-receiver
macth:
componnet: memcache
分组
有时候会遇到这样的场景:一台主机挂了后,主机上所有的服务都会挂掉,此时 alertmanager 会连续接收到很多的告警;如果每条告警都发一个邮件出去给接收者,那么短时间内邮件的发送量会很大
alertmanager 的分组功能可以把多条告警信息,合并成一个邮件发送出去
route:
receiver: admin-receiver
group_by: ["instance"]
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
- Group By
设置了group_by ["instance"]
,那么,当 AlertManager 接收到如下告警时
便会创建一个Group:{instance="peng01"}
,然后把该条告警加入到这个Group中。接着,如果再接收到一条告警
{alertname="NodeMemory",instance="peng01",job="node-exporter",serverity="high",...} time, annotation
也会加入到这个 Group 中
如果接收到另一个告警
那么便会创建 Group {instance="peng02"}
,然后把这条告警放在这个 Group 中
注意:只有当一个新的告警到达,且它不属于任何已经存在的分组时,才会创建新的分组
而如果接到了一个告警,它没有instance=xxx
这个 Label,那么就会创建一个 Group {}
,把这个告警加入到这个 Group 中
- Group Wait
当设置了 Group By 后,alertManager 会对告警进行分组。当一条告警到达时,如果它不属于任何一个已存在的分组,alertManager 会创建一个新的分组,然后将该告警加入到这个分组中。此时,alertManager 并不会立即把这个告警发给 Receiver,而是会等待 group_wait
的时间,如果在这个时间里有属于这个分组的其它告警到达,那么在 group_wait
时间后,alertManager 会把这一组告警一次性发给 Receiver。
注意:是创建一个分组后,才会等待 group_wait
的时间,等待其他属于这个分组的告警加入。当一个分组里面的告警都已经被 “解决”(Resolved)后,这些告警与分组都会删掉,如果再来一个告警,则会重新创建分组
- Group Interval
新的 Group 创建后,要等待 group_wait
的时间才会发通知给 Receiver。当发送了通知以后,它会等待 group_interval
的时间,在这段时间内到达该 Group 的告警,会在 group_interval
后,会作为一个通知发送给 Receiver(这个通知中会包含该分组内所有的告警)
假设 group_interval
为 5 分钟,某个分组最后一次发送通知的时间为 T,当 [T, T+5m]
的时间内该分组没有告警到达,而 T+6m
时该分组内有一个告警到达,那么这个告警会立即被发送给 Receiver,而不会等到 T+10m
才发送。然后把 T+6m
作为最后一次发送通知的时间
- Repeat Interval
当 alertManager 为某个分组发送了一个通知后,如果该分组里面的告警依然存在(即没有被 “解决”)且在 repeat_interval
的时间内没有接收到新的告警,那么在等待 repeat_interval
时间后,alertManager 才会为该分组重新发送一个通知
比如说,repeat_interval
为 4 小时,T 时刻 alertManager 为某个分组发送了最后一个通知,这个通知包含了多个告警。在 [T, T+4h]
的时间里,该分组没有接收到新的告警,那么在 T+4h
时 alertmanager 才会为该分组重新发送一个通知
重复发送告警的排查
告警 group 列表理解:在 alertManager 中,同 group 的告警,在 group_interval 的时间段内触发,会聚合到一个列表,当 prometheus 下次扫描告警规则时,发现告警列表中的告警(新增/恢复),才会触发告警
比如一个 group 的告警 A, B,C 在 30s 触发,聚合到一个告警列表发送。在下次扫描规则时,A,B,C 持续异常,且没有别的告警,不会发送告警列表;如果存在新告警 D,告警列表会加入 D,此时告警列表存在 A, B, C, D,才会发送告警(原列表中告警恢复也会发送)
如果告警 A,B,C 一直异常,也没有新增告警,直到 repeat_interval 的间隔时间,也会发送