昨天下午,一同事对我说 Prometheus 告警触发了,但是没发现对应的结果,我让她发了对应的截图给我:

pic1.png

原来同事使用了图一的查询来监控服务状态码为 4xx, 且非 400 和 419 的情况。

这个查询的逻辑看上去很合理,首先计算 4xx 的总数,然后再减去 400 和 419 的总数,最后查看计算结果是否 > 0 。

但通过图一和图二我们不难发现以下两个问题:

  • 图一查询结果怎么会有负数。
  • 根据图二结果可知,不存在非 400和 419 的 4xx 数据,但为何图一查询结果却有 > 0 的情况。

这两个问题,其实本质上是一个问题,那就是浮点数的精度问题,对于这个问题,我在 github 提了一个 issue, 得到的回复也大相径庭。

pic2.png

所以,我们需要尽量避免浮点数运算,尤其使用除法和减法来做监控告警的依据。

那回到同事这个需求,我们可以采用聚合的正则匹配来解决,其语句应该是这样:

pic3.png

变通了一下,查询语句简单不少,性能也有所提升。

总结

凡是能够直接通过查询搞定的,就不要再用计算表达式;如果用了表达式,需要注意精度问题,尤其做减法和除法。