教你一招,告警恢复时如何拿到恢复时的值?

Prometheus 生态的原生做法,由于阈值是放在 promql 中的,恢复时的消息中难以拿到恢复时的值,夜莺 v7.0.0.beta10 版本开始,提供了一种较为简单的内置方式,解决这个问题。下面我们就来看一下如何实现这个能力。

升级方法

从 v6 版本开始,程序自动创建表结构,所以 v6、v7 的各个小版本之间升级,相对容易,整体逻辑是:

  • 1.备份,包括数据库、二进制、配置文件、integrations目录,以防万一
  • 2.下载新版本解压,修改配置文件中的数据库连接地址、redis连接地址、时序库连接地址等个性化信息
  • 3.停掉老版本,启动新版本(建议新老版本使用不同的安装目录,都保留不删,建个软链指向当前使用的版本)

拿到恢复时的值的原理

夜莺的告警逻辑是拿着规则中的 promql 去周期性查询,如果查不到数据就认为是正常的,如果查到了数据,就认为有触发了阈值的异常数据,进而生成告警事件。从这里逻辑可以看出,恢复的时候,promql 查不到数据,所以也就难以拿到恢复的时候的值了。

有两个办法可以解决:

  • 不要把阈值放到 promql 中了,promql 查询原始数据,然后在告警引擎里边判断是否触发了阈值,而不是让时序库去判断,Flashduty 和夜莺企业版就提供了这个方式,这个方式比较容易理解,但是每次 promql 把原始数据查出来,可能会查出特别大量的数据,要小心使用
  • 在告警恢复的时候,重新发起一次 promql 查询,查询当前最新值。但是要注意,比如 10 台机器同时触发了 load1 告警,某个时刻有 2 台恢复了,查询最新值的 promql 得是准确去查询恢复的 2 台,得对应起来

开源版本的夜莺,提供的是第二种方式,下面我们来看一下如何配置。

如何配置

要配置两个地方,第一个是通知模板,我以钉钉的通知模板举例,其他的通知模板大家可以参考钉钉的:

复制代码
#### {{if .IsRecovered}}<font color="#008800">💚{{.RuleName}}</font>{{else}}<font color="#FF0000">💔{{.RuleName}}</font>{{end}}

---
{{$time_duration := sub now.Unix .FirstTriggerTime }}{{if .IsRecovered}}{{$time_duration = sub .LastEvalTime .FirstTriggerTime }}{{end}}
- **告警级别**: {{.Severity}}级
{{- if .RuleNote}}
- **规则备注**: {{.RuleNote}}
{{- end}}
{{- if not .IsRecovered}}
- **当次触发时值**: {{.TriggerValue}}
- **当次触发时间**: {{timeformat .TriggerTime}}
- **告警持续时长**: {{humanizeDurationInterface $time_duration}}
{{- else}}
{{- if .AnnotationsJSON.recovery_value}}
- **恢复时值**: {{formatDecimal .AnnotationsJSON.recovery_value 4}}
{{- end}}
- **恢复时间**: {{timeformat .LastEvalTime}}
- **告警持续时长**: {{humanizeDurationInterface $time_duration}}
{{- end}}
- **告警事件标签**:
{{- range $key, $val := .TagsMap}}
{{- if ne $key "rulename" }}
  - `{{$key}}`: `{{$val}}`
{{- end}}
{{- end}}

这里最为关键的逻辑是判断 .AnnotationsJSON.recovery_value 的逻辑:

复制代码
{{- if .AnnotationsJSON.recovery_value}}
- **恢复时值**: {{formatDecimal .AnnotationsJSON.recovery_value 4}}
{{- end}}

如果 .AnnotationsJSON 中包含 recovery_value 就展示,展示的时候把 recovery_value 保留 4 位小数。这个 .AnnotationsJSON 是夜莺告警规则中的自定义字段部分,如果告警事件中有恢复时的值,就会在这个字段中体现。

另一个要配置的,是告警规则,你想让哪个告警规则支持获取恢复时的值,就在告警规则的自定义字段中加上 recovery_promql 字段。比如我有一个告警规则用来侦测 HTTP 地址探测失败:

需要在告警规则最下面的自定义字段里,增加 recovery_promql 的配置,如下:

要理解这个工作逻辑,我们先来看看 http_response_result_code 这个指标的数据长什么样子:

从上图可以看出,这个指标包含两个 series,其中 agent_hostname 和 method 字段相同,target 字段可以区分开这俩 series。告警规则 http_response_result_code != 0 如果触发,告警事件中一定会带有 target 标签,所以,如果告警事件恢复的时候,我们用高警时的那个 target 标签去查询,一定就可以准确查到恢复时的值了。所以 recovery_promql 的配置中引用了 target 标签,其值是变量,这个变量就是告警事件中的 target 标签值。

效果

本文作者:秦晓辉,GitHub ID:UlricQin,开源监控产品 Open-Falcon、Nightingale 创始人,极客时间《运维监控系统实战笔记》作者,目前在监控/可观测性领域创业中。

相关推荐
牛奶咖啡131 天前
Prometheus+Grafana构建云原生分布式监控系统(十二)_基于DNS的服务发现
云原生·prometheus·dns·搭建自己的dns服务器·使用bind搭建dns服务器·配置正向解析·基于dns的服务发现
A-刘晨阳2 天前
Prometheus + Grafana + Alertmanager 实现邮件监控告警及配置告警信息
运维·云计算·grafana·prometheus·监控·邮件
饺子大魔王的男人2 天前
告别服务器失联!Prometheus+Alertmanager+cpolar 让监控告警不局限于内网
运维·服务器·prometheus
牛奶咖啡133 天前
Prometheus+Grafana构建云原生分布式监控系统(十一)_基于consul的服务发现
云原生·prometheus·consul的安装部署·consul服务自动发现·consul服务的注册删除·consul服务的更新·实现自动去consul注册服务
Otto_10274 天前
在 OpenStack Rocky 中部署 Prometheus + Grafana
openstack·grafana·prometheus
牛奶咖啡134 天前
Prometheus+Grafana构建云原生分布式监控系统(十)_prometheus的服务发现机制(一)
云原生·prometheus·prometheus服务发现·静态服务发现·动态服务发现·基于文件的服务发现配置实践·prometheus标签重写
玄德公笔记4 天前
Prometheus监控k8s的metric详解(第二版)-01-scrape 指标抓取
kubernetes·k8s·prometheus·监控·metric·scrape·k8s监控
小北方城市网4 天前
Spring Boot Actuator+Prometheus+Grafana 生产级监控体系搭建
java·spring boot·python·rabbitmq·java-rabbitmq·grafana·prometheus
牛奶咖啡135 天前
Prometheus+Grafana构建云原生分布式监控系统(九)_pushgateway的使用
云原生·grafana·prometheus·pushgateway·pushgateway使用场景·推数据到pushgateway·pushgateway的使用
AC赳赳老秦6 天前
Notion+DeepSeek:搭建个人工作看板与自动化任务管理规则
前端·javascript·人工智能·自动化·prometheus·notion·deepseek