Prometheus:如何计算单值随时间的比例

Prometheus: How to calculate proportion of single value over time

我想计算给定指标在某个时间范围内非零的时间百分比。我知道我可以使用

获取该时间范围内的值的数量

count_over_time(my_metric[1m])

但我想要的是

count_over_time(my_metric[1m] != 0) / count_over_time(my_metric)

我不能这样做,因为 binary expression must contain only scalar and instant vector types

有没有办法做我正在尝试的事情?

如果取值只能是0或1,那么可以用avg_over_time

如果它可以有其他值,那么你需要通过记录规则将其转换为0或1:

my_metric_nonzero = my_metric != bool 0

然后你可以avg_over_time(my_metric_nonzero[1m])

另见 https://www.robustperception.io/composing-range-vector-functions-in-promql/

自 Prometheus 2.7 起,you can do this using a subquery

具体而言,以下查询将使用尾随 1 小时平均值告诉您查询非零时间的百分比。

avg_over_time((my_metric[1m] != bool 0)[1h:])

请注意,链接的教程建议您仍然使用记录规则“以避免在每个评估间隔重新计算整个小时的子查询输出值。”

虽然Prometheus提供了subqueries,可以用来估计不等于0的样本的比例,但这并没有给出准确的值。例如,以下查询给出了过去一小时内 non-zero my_metric 值的估计比例:

avg_over_time((my_metric !=bool 0)[1h:30s])

但如果:(上例中的30s)后方括号中的step值大于存储在原始样本之间的间隔,则估计可能不正确普罗米修斯(又名 scrape_interval)。在这种情况下,计算估计值时仅考虑一部分原始样本。如果 step 小于 scrape_interval,则某些原始样本可能会被多次计数。

此问题已在 MetricsQL with count_ne_over_time 函数中修复。例如,以下查询 returns 最近一小时 non-zero my_metric 个样本的实际比例:

count_ne_over_time(my_metric[1h], 0) / count_over_time(my_metric[1h])

如果 my_metric 个样本总是 non-negative,则可以使用 share_gt_over_time:

进一步简化查询
share_gt_over_time(my_metric[1h], 0)