Prometheus作为专业的监控体系,有自己专门的报警插件Alertmanager;Alertmanager是一个独立的告警模块,接收Prometheus等客户端发来的警报,之后通过分组、删除重复等处理,并将它们通过路由发送给正确的接收器;告警方式可以按照不同的规则发送给不同的模块负责人,Alertmanager支持Email, Slack,等告警方式, 也可以通过webhook接入钉钉等国内IM工具。
先上一张基本基本的示意图:
Prometheus智能化报警流程避免邮件轰炸
由于换了新的工作环境,报警方面公司有统一报警平台,这里自己写了一个webhook来进行对接,把alertmanager收到的警报流发送到报警平台,之后其他人可以在报警平台进行警报订阅。实践过程中对Alertmanager配置有了更深的理解。这里总结分享一下。

首先警报的激活是由Prometheus Server的Alert Rule引起的,Alert Rule可以设置阀值,当达到rule设置的阀值时发送警报给Alertmanager。所以警报具体的发送时间跟Prometheus和Alertmanager的配置密切相关。这里有几个关键的配置。
Prometheus相关:

1. scrape_interval: How frequently to scrape targets default=1m。Server端抓取数据的时间间隔
2. scrape_timeout: How long until a scrape request times out. default = 10s 数据抓取的超时时间
3. evaluation_interval: How frequently to evaluate rules. default = 1m 评估报警规则的时间间隔

Alertmanger相关:

1. group_wait: How long to initially wait to send a notification for a group of alerts. Allows to wait for an inhibiting alert to arrive or collect more initial alerts for the same group. (Usually ~0s to few minutes. default = 30s)发送一组新的警报的初始等待时间,也就是初次发警报的延时
2. group_interval:How long to wait before sending a notification about new alerts that are added to a group of alerts for which an initial notification has already been sent. (Usually ~5m or more. default = 5m)初始警报组如果已经发送,需要等待多长时间再发送同组新产生的其他报警
3. repeat_interval: How long to wait before sending a notification again if it has already been sent successfully for an alert (Usually ~3h or more. default = 4h ) 如果警报已经成功发送,间隔多长时间再重复发送

另外说下Alert的三种状态:

1. pending:警报被激活,但是低于配置的持续时间。这里的持续时间即rule里的FOR字段设置的时间。改状态下不发送报警。
2. firing:警报已被激活,而且超出设置的持续时间。该状态下发送报警。
3. inactive:既不是pending也不是firing的时候状态变为inactive

需要注意一点:只有在评估周期期间,警报才会从当前状态转移到另一个状态。
介绍完上面几个概念,下面详细讲解下prometheus的报警流程。
我这里先定义一个名为"InstanceDown"的报警规则(Alert Rule):

alert: InstanceDown
expr: up == 0
for: 1m
labels:
severity: critital
annotations:
description: '{{ $labels.instance }} of job {{ $labels.job }} has been down for
more than 1 minutes.'
summary: Instance {{ $labels.instance }} down

该规则会检测后端实例的存活状态,当后端实例接口down的时候,“UP”的值会变为0;并设置FOR的持续时间为1min。
现在添加一个不存在的接口A:<“http://127.0.0.1:1234”>,作为测试
那么报警处理流程如下:

  1. Prometheus Server监控目标主机上暴露的http接口(这里假设接口A),通过上述Promethes配置的'scrape_interval'定义的时间间隔,定期采集目标主机上监控数据。
  2. 当接口A不可用的时候,Server端会持续的尝试从接口中取数据,直到"scrape_timeout"时间后停止尝试。这时候把接口的状态变为“DOWN”
    Prometheus智能化报警流程避免邮件轰炸
  3. Prometheus同时根据配置的"evaluation_interval"的时间间隔,定期(默认1min)的对Alert Rule进行评估;当到达评估周期的时候,发现接口A为DOWN,即UP=0为真,激活Alert,进入“PENDING”状态,并记录当前active的时间;
    Prometheus智能化报警流程避免邮件轰炸
  4. 当下一个alert rule的评估周期到来的时候,发现UP=0继续为真,然后判断警报Active的时间是否已经超出rule里的‘for’ 持续时间,如果未超出,则进入下一个评估周期;如果时间超出,则alert的状态变为“FIRING”;同时调用Alertmanager接口,发送相关报警数据。
    Prometheus智能化报警流程避免邮件轰炸
  5. AlertManager收到报警数据后,会将警报信息进行分组,然后根据alertmanager配置的“group_wait”时间先进行等待。等wait时间过后再发送报警信息。注意对比这里的上下两张图,上图Prometheus Active的时间是“08:22:23”,下图Alertmanager收到警报信息的时间是"08:23:23",正好是一个'evaluation_interval’评估周期。
    Prometheus智能化报警流程避免邮件轰炸
  6. 属于同一个Alert Group的警报,在等待的过程中可能进入新的alert,如果之前的报警已经成功发出,那么间隔“group_interval”的时间间隔后再重新发送报警信息。比如配置的是邮件报警,那么同属一个group的报警信息会汇总在一个邮件里进行发送。
    Prometheus智能化报警流程避免邮件轰炸
  7. 如果Alert Group里的警报一直没发生变化并且已经成功发送,等待‘repeat_interval’时间间隔之后再重复发送相同的报警邮件;如果之前的警报没有成功发送,则相当于触发第6条条件,则需要等待group_interval时间间隔后重复发送。
  8. 同时最后至于警报信息具体发给谁,满足什么样的条件下指定警报接收人,设置不同报警发送频率,这里有alertmanager的route路由规则进行配置。同时也可以使用自定义的webhook。这里暂时先不做具体详解。
    Prometheus智能化报警流程避免邮件轰炸

    理解了以上的报警处理流程,我们可以把报警信息进行分组汇总,同组的报警只发送一封报警邮件。可以根据route规则,不同警报的报警级别进行自定义的频率发送设置,指定接收人等,避免了现在的邮件轰炸报警模式。
    当然在没有理解这种报警处理流程之前,也踩了不少坑,这里也一起分享一下。

  9. Alert Rule "FOR"字段设置:如果有配置‘FOR‘’字段的话,alert状态会先变为peding,那么报警信息从server发出的最短时间间隔是一个evaluation_interval评估周期。假如不配置for或for设为0,则alert被激活后会立即变为firing状态,同时发送相关报警信息给alertmanager。
  10. group_wait的时间设置:如果设置时间过长,会导致报警发出有延迟;配置时间过短,同时会导致大量的邮件轰炸。这里建议根据不同警报重要性进行配置。