time-seriesprometheusgrafanavictoriametrics

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


Let's say i have a prometheus time series showing the power consumption from my power panel. I want to get the average consumption from 02:00 to 08:00 and from 15:00 to 17:00 on the same day and show them on the same panel in grafana. Assume that i have a time series of the above data starting from 00:00 and ending at 23:59 on the same day with a data point each second. I have tried playing with relative times, intervals and offsets but it is so frustrating i have been confused. Victoria metrics is also supported as i am using it to store the data series. I am thinking on changing to influxdb because it seems clearer to me how to do that with the language it supports but i would like to stay to just prometheus and victoriametrics.

i tried getting the first time range from 02:00 to 08:00 by using offsets and time intervals grafana offers but i failed. Even if it worked, i then would not have any clue how to do that with the other time range from 15:00-17:00.


Solution

  • To get average value of metric my_metric over window of time between 02:00 and 08:00 of current date, with preserving result till the midnight, you can use following query:

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

    What's happening here:


    Total query according to what you described in question will look like this (even though I still believe that there is no sence what so ever in addition of two averages):

    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:])