Prometheus 编写告警规则应对 metric 丢失的问题

问题描述

Prometheus 很重要的一个功能是监控告警,比如一个服务 X 暴露了两个 metric:A,B,我们需要 metricA 的取值是 0 或 1,当 metricA == 1 时,说明业务有问题,需要触发告警。当服务 X 一直运行是上面的告警逻辑容易实现,expr: X{metric="metricA"} == 1 即可搞定。实际情况是,服务 X 本身可能挂掉,导致 prometheus 在服务 X 挂掉这段时间收到的 metricA 是缺失的,这个时候告警规则就不好写了,针对某些 metric 缺失的情况,如何来编写告警规则呢?

prometheus missing metric

如何编写告警规则

Prometheus 告警规则编写语法参考官网:ALERTING RULES
告警规则示例:

groups:
- name: example
  rules:
  - alert: HighRequestLatency
    expr: job:request_latency_seconds:mean5m{job="myjob"} > 0.5
    for: 10m
    labels:
      severity: page
    annotations:
      summary: High request latency

尽量避免丢失 metric

对于不是 metric exporter 服务本身失败的情况,应该尽量避免程序暴露 metric 的时候出现丢失 metric 的情况。官方也是建议尽量避免丢失 metric 的,因为这会对后续很多处理带来不便。avoid-missing-metrics

解决办法

对于 missing metric 的情况设置默认值

这个想法主要来源于 open-falcon ,open-falcon 是 push 模式的监控系统,在 server 侧可以针对某个 metric 值为空的情况设置一个默认值的功能,通常我会把 metric 为空的时候将对应的 value 设置为 -1 这样的值而不是设置为 0,这样在写告警规则的时候容易进行区别判断。

结果是检查了 prometheus 相关的资料,并无此功能。

使用 absent 内置函数

PromQL 内置的 absent 函数可以用来判断某个瞬时向量是否存在,看起来有戏。

absent(v instant-vector) returns an empty vector if the vector passed to it has any elements and a 1-element vector with the value 1 if the vector passed to it has no elements.
This is useful for alerting on when no time series exist for a given metric name and label combination.

对于上面描述的那个问题,服务 X 暴露了 metricA,如果有我们有 5 台服务器,每个服务器上面跑了一个服务 X,当我们使用 PromQL 语句(up{job=“x-service”})去检索的时候,会返回包含 5 个instance 的 metric。但是当 absent 函数作用于 up{job=“x-service”},absent(up{job=“x-service”}) 会对所有 instance 做聚合处理,只要 5 个 instance 中有一个 instance 的值非空,absent(up{job=“x-service”})返回的就是空,只有当所有 instance 的值为空时,absent(up{job=“x-service”}) 才会返回 1。但是我们期望 absent 返回的结果是针对 5 个 instance 分别返回值是否为空的情况。目前 absent 无法解决该问题。

absent
absent

unless

vector1 unless vector2 会产生一个新的向量,新向量中的元素由vector1中没有与vector2匹配的元素组成。

offset + unless

count(up{job="x-service"} offset 1h) by (instance) unless count(up{job="x-service"}) by (instance)

使用本 metric offset 然后 unless 来达到类似取反的结果。但是仔细看这个表达是会发现这个表达式无法达到取反的效果,只能解决一部分告警触发的情况,对于告警解除的触发通常是有问题的。

取一个每个 instance 都会暴露一个且不会为空的 metric + unless

这个方法关键是要找到一个每个 instance 都会暴露且不会为空的 metric (metricZ)作为 vector1 来跟 metricA 做 unless,这样就相当于对 metricA 取反。为了确保 metricZ 的 label 能够跟 metricA 对应上,可以使用 label_replace 来确保 metricZ 和 metricA 的 instance 这个 label 能够对应上。

up{job="federate_http"} == 1 UNLESS ON(instance) label_replace(up{type="x-service"}, "instance", "$1:30900", "instance",  "(.*):.*")
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值