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

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 创始人,极客时间《运维监控系统实战笔记》作者,目前在监控/可观测性领域创业中。

相关推荐
菜鸟挣扎史1 天前
grafana+prometheus+windows_exporter实现windows进程资源占用的监控
windows·grafana·prometheus·进程·process
牙牙7053 天前
Prometheus结合K8s(二)使用
容器·kubernetes·prometheus
牙牙7054 天前
Prometheus结合K8s(一)搭建
容器·kubernetes·prometheus
福大大架构师每日一题4 天前
32.2 prometheus倒排索引统计功能
ios·iphone·prometheus
让生命变得有价值6 天前
使用 Grafana api 查询 Datasource 数据
grafana·prometheus
福大大架构师每日一题6 天前
31.3 XOR压缩和相关的prometheus源码解读
prometheus
赫萝的红苹果6 天前
Springboot整合Prometheus+grafana实现系统监控
spring boot·grafana·prometheus
Heartsuit6 天前
云原生之运维监控实践-使用Prometheus与Grafana实现对Nginx和Nacos服务的监测
nginx·云原生·nacos·grafana·prometheus·运维监控
Heartsuit6 天前
云原生之运维监控实践-使用Telegraf、Prometheus与Grafana实现对InfluxDB服务的监测
云原生·grafana·prometheus·influxdb·telegraf·运维监控
武子康11 天前
大数据-218 Prometheus 插件 exporter 与 pushgateway 配置使用 监控服务 使用场景
大数据·hive·hadoop·flink·spark·prometheus