returning MAX by DAY aggregated by STATUS by $__range

143 views
Skip to first unread message

Stefano Mantini

unread,
May 19, 2023, 6:10:14 AM5/19/23
to Prometheus Users
 I’m looking at an efficient way of returning the MAX of each day’s metrics in a given time period

The metric is a Gauge Vector that identifies each Validator by public key, and the value represents an ENUM value.

Example
validator_statuses{pubkey="pk0"} 0 // UNKNOWN
validator_statuses{pubkey="pk1"} 1 // DEPOSITED
validator_statuses{pubkey="pk2"} 2 // PENDING
validator_statuses{pubkey="pk3"} 3 // ACTIVE
validator_statuses{pubkey="pk4"} 4 //EXITING
validator_statuses{pubkey="pk5"} 5 // SLASHING
validator_statuses{pubkey="pk6"} 6 //EXITED

I am retrieving the MAX by Day using this query:
max_over_time( validator_statuses{} [1d])

Which returns the timestamp of the day, the pubkey and the MAX status for that timestamp day
+---------------------+--------+--------+
|        Time         | Pubkey | Status |
+---------------------+--------+--------+
| 2023-05-01 00:00:00 | 0x0    |      1 |
| 2023-05-02 00:00:00 | 0x0    |      2 |
| 2023-05-03 00:00:00 | 0x0    |      2 |
| 2023-05-04 00:00:00 | 0x0    |      3 |
| 2023-05-05 00:00:00 | 0x0    |      3 |
| 2023-05-06 00:00:00 | 0x0    |      3 |
| 2023-05-07 00:00:00 | 0x0    |      3 |
| 2023-05-08 00:00:00 | 0x0    |      3 |
| 2023-05-09 00:00:00 | 0x0    |      3 |
| 2023-05-010 00:00:00| 0x0    |      3 |
+---------------------+--------+--------+

However, i'm having trouble when trying to count by and aggregate those statuses
My intention is to count the number of days a validator is in each status per $__range, the above data would return this kind of tablular data

+--------+-----------+------------------+------------------+------------------+
| Pubkey | StatusNow | Days In Status 1 | Days In Status 2 | Days In Status 3 |
+--------+-----------+------------------+------------------+------------------+
| 0x0    |         3 |                1 |                2 |                7 |
+--------+-----------+------------------+------------------+------------------+


Can this be done entirely in PromQL? Or will i have to leverage multiple queries and aggregate in Grafana? 

All information and attachments included in this email are confidential and intended for the original recipient only. You must not share any part of this message with any third party. If you have received this message by mistake, please let us know immediately, so that we can make sure such a mistake does not happen again and delete this message from your system.

Brian Candler

unread,
May 19, 2023, 7:11:54 AM5/19/23
to Prometheus Users
Unfortunately, you can't apply value filters to range vectors

validator_statuses[1d] # this is OK
validator_statuses{foo="bar"}[1d] # this is OK
(validator_statuses == 2)[1d] # NOT IMPLEMENTED

(there are several scenarios in which I'd find this useful).  The best you can do is a subquery:

(validator_statuses == 2)[1d:1m]

This evaluates the inner expression repeatedly at different times 1m apart. That will *approximate* what you want if the scraping interval for that metric is also 1m; however each evaluation will look back up to 5 minutes to find a value, so missing scrapes will be seen as the value of the previous scrape.

Brian Candler

unread,
May 19, 2023, 1:27:23 PM5/19/23
to Prometheus Users
Correction, what I meant to write was

validator_statuses[1d] == 2 # NOT IMPLEMENTED

But the subquery was correct (I think!)

There is a similar thread about counting how many times up==1 in a range:
Reply all
Reply to author
Forward
0 new messages