有没有办法在 prometheus 时间序列中选择 2 个不同的时间范围并将它们显示在 grafana 的同一面板上?

Is there a way to select 2 different time ranges in a prometheus time series and show them at the same panel in grafana?

提问人:soilah 提问时间:11/16/2023 更新时间:11/19/2023 访问量:45

问:

假设我有一个 prometheus 时间序列,显示了电源面板的功耗。我想获取同一天 02:00 到 08:00 和 15:00 到 17:00 的平均消费量,并在 grafana 的同一面板上显示它们。假设我有一个上述数据的时间序列,从同一天 00:00 开始,到 23:59 结束,每秒一个数据点。我试过玩相对时间、间隔和偏移量,但这太令人沮丧了,我一直很困惑。也支持 Victoria 指标,因为我使用它来存储数据系列。我正在考虑更改为 influxdb,因为对我来说似乎更清楚如何使用它支持的语言来做到这一点,但我想只使用 prometheus 和 victoriametrics。

我尝试使用 grafana 提供的偏移量和时间间隔来获取从 02:00 到 08:00 的第一个时间范围,但我失败了。即使它有效,我也不知道如何在 15:00-17:00 的其他时间范围内做到这一点。

时间序列 Prometheus Grafana Victoriametrics

评论

0赞 markalex 11/16/2023
你能更详细地解释一下吗?您想显示图表 02-08,然后在它之后立即显示 15-17?或者你想并行看到它们?
0赞 markalex 11/16/2023
另外,为什么不简单地使用具有不同时移/相对时间配置的相邻面板呢?
0赞 soilah 11/16/2023
是的,对不起,这是我第一次问问题。我想取每个时间范围的平均值,并将它们汇总为一个值。类似 sum(avg(time_series[02:00-08:00]) + avg(time_series[15:00-17:00]))
0赞 markalex 11/16/2023
您是否希望面板显示单个值?它应该在 04:00 显示什么:平均 02-04,或昨天 04-08 + 昨天 15-17 + 今天 02-04?另外,avg(something) + avg(something_else) 应该代表什么?试图计算平均值吗?
0赞 soilah 11/17/2023
我希望面板显示一个值。两个平均值的总和。一段时间内的平均值为 02:00 至 00:08,另一次为 15:00 至 17:00。这些时间范围代表能源供应商的夜间能源价格,因此我想计算这些时间间隔消耗的总平均能源。在 04:00,我希望面板显示平均 02:00-04:00,因为计算仅对每一天有意义。总之,我希望每个不同的日期都显示夜间消耗的总能量、能源价格、时间范围和白天(当我找到夜晚时会很容易)。

答:

0赞 markalex 11/19/2023 #1

要获取当前日期 02:00 到 08:00 之间的时间窗口的指标平均值,并将结果保留到午夜,您可以使用以下查询:my_metric

avg_over_time(
 (my_metric
  and on() (
    (hour() >= 2<8) 
    and
    floor(vector(time())/86400) == on() floor(topk(1,timestamp(up@end()))/86400)
  )
 ) 
[24h:])

这里发生了什么:

  • avg_over_time计算指定范围向量的平均值。在这种情况下,我们需要简单的平均值,因为所有过滤都将在范围选择器内进行。
  • my_metric and on()获取指标并根据以下表达式对其进行过滤,忽略所有标签。
    • hour() >= 2<8)第一个过滤表达式:函数应返回大于或等于 2 且小于 8 的值,hour()
    • and第二个表达式必须与第一个表达式同时为 true。不需要,因为两个表达式都没有任何标签。on()
    • floor(vector(time())/86400) == on() floor(topk(1,timestamp(up@end()))/86400)第二个筛选表达式,仅获取当天内与查询时间范围结束相对应的指标值。更多解释:
      • floor(vector(time())/86400)只需按 86400 计算时间戳的整除部分。这是为了查找值所属的一天的 00:00:00。
      • floor(topk(1,timestamp(up@end()))/86400)与前一个类似,但它计算当天的 00:00:00,属于所选时间范围的结束(在您的例子中为 Grafana 中的仪表板选择的范围结束)。这里只是在范围端返回指标的值,然后提取它的时间戳。 仅用于获取结果的一个值(指标具有多个值,使用是任意的,并且整个构造可以替换为某个指标,该指标可以随时保证具有单个值)。up@end()uptimestamptopk(1, .. )upup

根据您所描述的内容,总查询将如下所示(尽管我仍然相信除了两个平均值之外没有任何意义):

avg_over_time(
 (my_metric
  and on() (
    (hour() >= 2<8) 
    and
    floor(vector(time())/86400) == on() floor(topk(1,timestamp(up@end()))/86400)
  )
 ) 
[24h:])
+
avg_over_time(
 (my_metric
  and on() (
    (hour() >= 15<17) 
    and
    floor(vector(time())/86400) == on() floor(topk(1,timestamp(up@end()))/86400)
  )
 ) 
[24h:])

评论

0赞 soilah 11/22/2023
你是对的,总结两个平均值是无稽之谈,我不会那样做。尽管如此,你帮了我很多,这就是我一直在寻找的!谢谢