有时您需要将一个指标除以另一个指标。
例如,我想像这样计算平均延迟:
rate({__name__="hystrix_command_latency_total_seconds_sum"}[60s])
/
rate({__name__="hystrix_command_latency_total_seconds_count"}[60s])
如果在指定时间段内没有活动,则分频器中的rate()
变为0
,分割结果变为NaN
。
如果我对结果(avg()
或sum()
或其他)进行一些汇总,则整个聚合结果将变为NaN
。
所以我在divider中添加了一个零检查:
rate({__name__="hystrix_command_latency_total_seconds_sum"}[60s])
/
(rate({__name__="hystrix_command_latency_total_seconds_count"}[60s]) > 0)
这会从结果向量中删除NaN
。并且撕掉图表上的线条以撕碎。
让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)
长话短说:有没有更简单的方法来处理分频器中的零?或者任何常见做法?
答案 0 :(得分:4)
如果在指定时间段内没有活动,则分频器中的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]))
答案 1 :(得分:1)
最后,我有一个针对特定问题的解决方案:
除以零会导致显示NaN-从技术上讲可以正常显示并且可以正确显示,但不能显示用户希望看到的内容(不满足业务要求)。
因此我进行了一些搜索,找到了grafana社区中的问题的“解决方案”:
用max(YOUR_PROLEMATIC_QUERY, or vector(-1))
包围您的问题价值。然后,附加的值映射将导致有用的输出。
(当然,您必须调整解决方案以解决您的问题...最小/最大... vector(42)/ vector(101)/ vector(...))
更新(1)
好的。然而。根据查询,似乎有些棘手。例如,我有另一个查询,由于除零导致NaN失败。上述解决方案不起作用。我必须用括号将查询括起来并添加 > 0 or on() vector(100)
。
答案 2 :(得分:0)
根据@eventhorizen 的回答,如果您有一个查询作为分母,有时会返回零,它可能会弄乱图表并在没有数据的情况下显示无穷大,您可以将结果限制在有效范围内。
例如,这个指标的输出应该在 0 到 1 之间,但是当没有数据时它也会产生 INFINITY:
(1/increase(SOMETIMES_ZERO_QUERY[1m]))
在这种情况下,您可以改为这样写,因此它显示 0
而不是大于 100
的值:
max((1/increase(SOMETIMES_ZERO_QUERY[1m]))<100 or on() vector(0))
或者如果你想要 1
作为无穷大:
max((1/increase(SOMETIMES_ZERO_QUERY[1m]))<100 or on() vector(1))