有时,您需要将一个度量除以另一个度量。
例如,我想计算这样的平均延迟:
rate({__name__="hystrix_command_latency_total_seconds_sum"}[60s])
/
rate({__name__="hystrix_command_latency_total_seconds_count"}[60s])如果在指定的时间段内没有活动,则除法器中的rate()变成0,除法的结果变成NaN。如果我对结果(avg()或sum()或其他什么)进行一些聚合,则整个聚合结果将变成NaN。
所以我在除法器中加了一个零的检查:
rate({__name__="hystrix_command_latency_total_seconds_sum"}[60s])
/
(rate({__name__="hystrix_command_latency_total_seconds_count"}[60s]) > 0)这将从结果向量中删除NaNs。把图表上的线撕成碎片。
让我们用0值标记不活动期,使图形再次连续:
rate({__name__="hystrix_command_latency_total_seconds_sum"}[60s])
/
(rate({__name__="hystrix_command_latency_total_seconds_count"}[60s]) > 0)
or
rate({__name__="hystrix_command_latency_total_seconds_count"}[60s]) > bool 0这有效地取代了NaN的0,图形是连续的,聚合工作正常。
但是产生的查询有点麻烦,特别是当您需要进行更多的标签过滤和对结果进行一些聚合时。就像这样:
avg(
1000 * increase({__name__=~".*_hystrix_command_latency_total_seconds_sum", command_group=~"$commandGroup", command_name=~"$commandName", job=~"$service", instance=~"$instance"}[60s])
/
(increase({__name__=~".*_hystrix_command_latency_total_seconds_count", command_group=~"$commandGroup", command_name=~"$commandName", job=~"$service", instance=~"$instance"}[60s]) > 0)
or
increase({__name__=~".*_hystrix_command_latency_total_seconds_count", command_group=~"$commandGroup", command_name=~"$commandName", job=~"$service", instance=~"$instance"}[60s]) > bool 0
) by (command_group, command_name)长话短说:有没有更简单的方法来处理除法器中的零?或者有什么常见的做法吗?
发布于 2017-11-01 14:05:36
如果在指定的时间段内没有活动,则分隔符中的rate()变为0,除法的结果为NaN。
这是正确的行为,NaN是你想要的结果。
聚合工作正常。
你不能把比率相加。您需要将分子和分母分别聚合起来,然后再进行除法。
所以:
sum by (command_group, command_name)(rate(hystrix_command_latency_total_seconds_sum[5m]))
/
sum by (command_group, command_name)(rate(hystrix_command_latency_total_seconds_count[5m]))发布于 2020-06-15 14:00:44
最后,我对我的具体问题有了一个解决方案:
以零判断导致NaN显示--这作为技术结果很好,并且是正确的,但不是用户想要看到的(不满足业务要求)。
于是我搜索了一下,并在grafana社区找到了一个解决我的问题的“解决方案”:
用max(YOUR_PROLEMATIC_QUERY, or vector(-1))包围您有问题的值。然后,附加的值映射将导致有用的输出。
(当然,你必须适应你的问题.min/max..。向量(42)/vector(101)/vector(.))
更新(1)
好吧。然而。基于查询,它似乎要复杂一些。例如,我有另一个查询在NaN中失败,结果是退视率为零。以上解决方案不起作用。我不得不用括号包围查询,并添加了> 0 or on() vector(100)。
发布于 2022-03-30 11:53:00
只需将> smallest_value添加到查询中,然后将其包装到聚合函数(如avg() )中,其中smallest_value是值,它小于内部查询的任何预期有效结果。例如:
avg((
rate({__name__="hystrix_command_latency_total_seconds_sum"}[60s])
/
rate({__name__="hystrix_command_latency_total_seconds_count"}[60s])
) > -1e12)当将NaN值与任何数字与>运算符比较时,Prometheus会删除它们。例如,NaN >bool -1e12。同样的情况也适用于<运算符,例如NaN <bool 1e12。因此,可以使用>或<来过滤NaN值,然后再用聚合函数聚合它们。
在MetricsQL中不需要这个技巧,因为当聚合函数被应用到VictoriaMtrics时,VictoriaMtrics会自动跳过它们的NaN值。
https://stackoverflow.com/questions/47056557
复制相似问题