为何Prometheus告警时,现场值总是无法获取?
摘要:Prometheus 生态已经成为新时代的监控标准,很多公司都用到了 Prometheus 生态的产品。在使用 Prometheus 过程中,经常有人困惑:为何在告警恢复时拿不到恢复时的值? 我们从原理来分析,帮大家解疑答惑。 Promet
Prometheus 生态已经成为新时代的监控标准,很多公司都用到了 Prometheus 生态的产品。在使用 Prometheus 过程中,经常有人困惑:为何在告警恢复时拿不到恢复时的值?
我们从原理来分析,帮大家解疑答惑。
Prometheus 告警原理
Prometheus 的整个告警流程,涉及两个进程:prometheus + alertmanager:
prometheus 进程负责周期性查询判定。用户在 prometheus.yaml 中配置告警规则,prometheus 进程根据这些 yaml 格式的 rules,周期性查询 TSDB,判定是否触发了阈值,如果查到了数据,会返回一堆 vectors,prometheus 就会把这堆 vectors 发给 alertmanager,一个 vector 就被看做一个告警事件。
以上例而言,告警规则所用的 promql 是:
disk_used_percent{fstype="virtiofs"} > 80
返回了 6 条数据,就是 6 个 vector,也就是会生成 6 条事件,发给 alertmanager(这里故意没有讲解 for 关键字,是为了更容易理解整个原理,咱们先理解基本原理)。
一般来讲,Prometheus 的 eval interval 是 15s,也就是每 15s 查询判定一次,就上例而言,如果这 6 个分区的磁盘利用率一直大于 80,那每次判定时,这 6 条数据都会发给 alertmanager。
再说 alertmanager,
alertmanager 收到事件之后,会进行消息发送。当然了,alertmanager 会有各种 silent、inhibit、group 之类的逻辑,姑且不论,最终就是发送。
对于告警事件,prometheus 查询 promql 时,TSDB 会返回告警时候的值,所以,告警事件中会带有 trigger value,也就是模板中可以引用的那个 $value 变量。
Prometheus 恢复原理
当谈到告警恢复时,逻辑就会绕一些了。就上例而言,磁盘利用率小于或等于 80 的时候,告警就恢复了。一旦数值小于或等于 80,那 prometheus 进程拿着 promql 去查询 TSDB 时,TSDB 发现没有数据符合条件,就不返回数据了。
此后每个计算周期,prometheus 都不会推送事件给 alertmanager。alertmanager 发现长时间(根据 resolve_timeout 配置来的)收不到事件了,就认为告警恢复了,产生恢复事件。
注意,alertmanager 产生恢复事件时,并没有收到 prometheus 的事件,而是把内存里之前缓存的告警事件修改了一下状态为 恢复,直接发出来了,所以,恢复时的 $value 并非是恢复告警的那一刻的即时值,而是之前告警触发时的值!
有办法获取恢复时的值吗
以笔者的理解,Prometheus 本身是做不到的。如果你有办法欢迎留言分享。
不过有个开源项目可以做到,就是开源夜莺:Nightingale。Nightingale 开源项目是一个告警引擎,既可以对 Prometheus、VictoriaMetrics 中的数据做告警,也可以对 ClickHouse、MySQL、ElasticSearch 中的数据做告警。
下面我们对夜莺项目做一个简介,同时介绍一些在 Nightingale 中如何配置即可获取恢复时的值。
夜莺项目简介
如果你已经了解过,可以跳过这部分内容。
夜莺监控(Nightingale)是一款侧重告警的监控类开源项目。类似 Grafana 的数据源集成方式,夜莺也是对接多种既有的数据源,不过 Grafana 侧重在可视化,夜莺是侧重在告警引擎、告警事件的处理和分发。
夜莺监控项目,最初由滴滴开发和开源,并于 2022 年 5 月 11 日,捐赠予中国计算机学会开源发展委员会(CCF ODC),为 CCF ODC 成立后接受捐赠的第一个开源项目。
