一般我们监控由prometheus发送告警给alertmanager,然后由alertmanager来推送告警,那么此时,告警的恢复除了prometheus来触发外,其实也可以由alertmanager来发送的
prometheus触发告警恢复:
对于已经恢复的告警指标,如果之前是pending或者之前的ResolvedAt非空,且
在resolvedRetention(15m)之前的,则删除此告警;
否则更新告警的状态为恢复,且恢复的时间为当前时间
对告警进行判断是否需要发送
恢复时间是大于上次发送告警的时间,证明恢复是在告警后发生的,那么已经恢复了,需发送恢复
设置告警的ValidUntil,如果这条告警过了ValidUntil的话,还没收到新firing,则代表恢复:
ValidUntil = ts + max([check_interval], [resend_delay]) * 4
发送前设置告警EndAt
发送告警
alertmanager触发告警恢复:
注意:Alertmanager 里必须有 Inactive 消息所对应的告警,否则是会被忽略的。换句话说如果一个告警在 Alertmanager 里已经解除了,再发同样的 Inactive 消息,Alertmanager 是不会发给 webhook 的。
Prometheus 需要 持续 地将 Firing 告警发送给 Alertmanager,遇到以下一种情况,Alertmanager 会认为告警已经解决,发送一个 resolved:
Prometheus 发送了 Inactive 的消息给 Alertmanager,即 endsAt=当前时间
Prometheus 在上一次消息的 endsAt 之前,一直没有发送任何消息给 Alertmanager
解释:prometheus发送给alertmanager的告警触发消息里是带有一个endAt时间,用来告知如果超过这个时间没有再收到新的告警就认为告警已经恢复,如果prometheus没有带endAt,那么alertmanager会设置endAt为now + resolve_timeout,作为默认恢复时间
prometheus会给告警加上一个默认endAt:ts + max([check_interval], [resend_delay]) * 4
原理:当AlertManager收到告警实例之后,会分以下几类情况对这两个字段进行处理:
即:如果 endsAt 没有提供,则自动等于 startsAt + resolve_timeout(默认 5m),如果有指定,则以指定的为准
alertmanager config中可以看到默认的resolve_timeout是5m,且是一个可以配置的值。
该参数定义了当Alertmanager持续多长时间未接收到告警后标记告警状态为resolved(已解决)。
该参数的定义会影响到告警恢复通知的接收时间。
global:[ resolve_timeout: | default = 5m ][ smtp_from: ] [ smtp_smarthost: ] [ smtp_hello: | default = "localhost" ][ smtp_auth_username: ][ smtp_auth_password: ][ smtp_auth_identity: ][ smtp_auth_secret: ][ smtp_require_tls: | default = true ][ slack_api_url: ][ victorops_api_key: ][ victorops_api_url: | default = "https://alert.victorops.com/integrations/generic/20131114/alert/" ][ pagerduty_url: | default = "https://events.pagerduty.com/v2/enqueue" ][ opsgenie_api_key: ][ opsgenie_api_url: | default = "https://api.opsgenie.com/" ][ hipchat_api_url: | default = "https://api.hipchat.com/" ][ hipchat_auth_token: ][ wechat_api_url: | default = "https://qyapi.weixin.qq.com/cgi-bin/" ][ wechat_api_secret: ][ wechat_api_corp_id: ][ http_config: ]templates:[ - ... ]route: receivers:- ...inhibit_rules:[ - ... ]
如果告警一直 Firing,那么 Prometheus 会在 resend_delay 的间隔重复发送,而 startsAt 保持不变, endsAt 跟着 ValidUntil 变。这也就是为啥一直firing的规则不会被认为恢复,而不发firting则会认为恢复。因为一直firing的告警消息中, endsAt 跟着 ValidUntil 变,一直在后延。而如果没收到,就会导致alertmanger那边在过了告警的endAt时间后,没收到恢复或者新firing,则认为恢复
prometheus采集到了告警恢复的情况,推送给alertmanager,alertmanager发出告警
prometheus发送了告警消息,且没有发生恢复告警,也没有持续发送触发告警,则alertmanger对一条活跃告警如果过了这条告警的endAt时间后会发出告警恢复的消息
当告警没有再此触发时,多久后发送恢复的时间由什么因素决定:告警的endAt来决定
即:对活跃告警的默认恢复时间决定为:如果发送方(prometheus等)指定了endAt,则以发送方为准,否则alertmanger统一设置为now + resolve_timeout,即一条告警等待了resolve_timeout还没收到新的告警内容,则视为恢复