假设我有一个普罗米修斯时间序列,显示我的电源面板的功耗。我想获得当天02:00到08:00和15:00到17:00的平均消费,并将它们显示在grafana的同一个面板上。假设我有一个上述数据的时间序列,从同一天的 00:00 开始到 23:59 结束,每秒一个数据点。我尝试过使用相对时间、间隔和偏移量,但这太令人沮丧了,我一直很困惑。维多利亚指标也受支持,因为我使用它来存储数据系列。我正在考虑更改为 influxdb,因为对我来说,如何使用它支持的语言来做到这一点似乎更清楚,但我想只使用 prometheus 和 victoriametrics。
我尝试使用 grafana 提供的偏移量和时间间隔获取从 02:00 到 08:00 的第一个时间范围,但失败了。即使它有效,我也不知道如何在 15:00-17:00 的其他时间范围内做到这一点。
要获取当前日期 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)
第一个过滤表达式:函数hour()
应返回大于或等于2且小于8之间的值,and
第二个表达式必须与第一个表达式同时为真。不需要 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()
只是返回范围末端的指标 up
的值,然后 timestamp
提取它的时间戳。 topk(1, .. )
用于仅获取结果的一个值(指标 up
有倍数,up
的使用是任意的,整个构造可以用某些保证在任何时候具有单一值的指标来替换)。根据您所描述的问题的总查询将如下所示(尽管我仍然相信除了两个平均值之外没有任何意义):
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:])