Grafana+Prometheus:区间起始数据有无时的差值与图表展示问题
问题解决方案
1. 让rc=B得到正确的差值2
核心是确保每个rc在查询区间的起始时刻都有一个0值,这样计算首尾差值时,rc=B的起始值会被认定为0而非第一个出现的1。
使用以下PromQL查询:
# 先按rc聚合指标 aggregated_counter = sum by(rc) (counter{label1=~"abc|def"}); # 按rc维度匹配,为缺失起始数据的rc补0 aggregated_counter or on(rc) group_left() vector(0)
在表格模式下选择Legend的"Difference"时,rc=B的差值会是2-0=2,rc=A的差值保持8-4=4,完全符合预期。
如果要直接计算差值,也可以一步到位:
last_over_time((sum by(rc) (counter{label1=~"abc|def"}) or on(rc) group_left() vector(0))[$__range]) - first_over_time((sum by(rc) (counter{label1=~"abc|def"}) or on(rc) group_left() vector(0))[$__range])
你之前用@end - @start报错,是因为@end/@start仅能获取单个时间点的序列,当某个rc在其中一个时间点无数据时,合并会丢失序列;而or on(rc) group_left()可以按维度保留所有rc的序列,避免丢失。
2. 让rc=A的曲线从0开始展示
有两种实现方式,按需选择:
方式一:修改PromQL输出增量
将每个时间点的数值转换为相对于区间起始时刻的增量,rc=A的起始值会变为0,后续数值为当前值与起始值的差:
# 获取每个rc在区间起始时刻的数值,无数据则补0 start_values = first_over_time((sum by(rc) (counter{label1=~"abc|def"}) or on(rc) group_left() vector(0))[$__range_start:$__range_start]); # 当前聚合值减去起始值,得到增量序列 sum by(rc) (counter{label1=~"abc|def"}) - start_values or vector(0)
这样rc=A的曲线从0开始,最终值为4(8-4);rc=B的曲线从0开始,最终值为2(2-0),完全满足展示需求。
方式二:使用Grafana Transformations
如果不想修改PromQL,可通过Grafana转换功能实现:
- 进入图表的Transform选项卡
- 添加
Add field from calculation转换,选择Difference from first - 注意:必须先解决第一个问题(补全rc=B的起始0值),否则rc=B的转换结果总增量仍为1。
内容的提问来源于stack exchange,提问作者Willheisen
相关产品推荐
相关产品推荐

