Reputation: 151
In Prometheus I'm trying to merge multiple http request lines into groups using label_replace
.
http_requests_total{account_id="124",handler="AAAAAController"...}
http_requests_total{account_id="125",handler="BBBBBController"...}
http_requests_total{account_id="126",handler="CCCCCController"...}
http_requests_total{account_id="123",handler="XXXXXController"...}
The query I wrote is :
label_replace(http_requests_total, "class", "$1", "handler", "([a-zA-Z0-9]+)Controller.*")
.
This works correctly and adds the class
label to vector :"AAAA","BBBB" etc. At this point I would like to remove certain classes such as empty and BBBB
.
How can I further filter the vector using {class~="BBBBB"}
:
label_replace(http_requests_total, "class", "", "handler", "([a-zA-Z0-9]+)Controller.*"){class~="BBBBB"}
Prometheus shows an error when I try to do so.
Upvotes: 15
Views: 5013
Reputation: 13360
As mentioned here already there is no easy and straightforward way of filtering this.
Some of the [simpler] filtering can be done with combination of set operators unless
, and
and or
.
So, if you want to leave only metrics with label l1
equal to values v1
or v2
or empty value (missing label l1
) you can use following:
<my_initial_query>
and on(l1) (
absent(_{l1="v1"}) or
absent(_{l1="v2"}) or
absent(_{})
)
Similarly, to exclude metrics with label l1
equal to values v1
or v2
or empty value (missing label l1
):
<my_initial_query>
unless on(l1) (
absent(_{l1="v1"}) or
absent(_{l1="v2"}) or
absent(_{})
)
Here, absent(_{l1="v1"})
produces pseudo-metric with label l1="v1"
(_
is simply used as a name of non-existing metric. You can use absent(non_existent{l1="v1"})
if it's easier).
Also, please note, that this trick is based on absent
"tr[ying] to be smart about deriving labels" as official documentation states. This trick only works for label selectors using =
. Something like l1=~"v1|v2|"
wouldn't work.
Demo queries showing this principle in action can be found here.
Upvotes: 0
Reputation: 1
I had the same problems and this is my solution:
label_repalce({__name__=~"foo($lable)"}, 'lable', ...)
The label is which you will generate, you can set it on Grafana. This method works for me.
Upvotes: 0
Reputation: 10325
solution:
You can achieve it via joining two metrics, for example I need to group pods by nodes filtered by the name of the deployment that I pass as grafana variable
count by (node)
(
label_replace(kube_pod_info{namespace="prod"}, "deployment", "$1", "pod", "(.*)-(.*)-(.*)$")
* on (deployment) group_left(job)
kube_deployment_labels{namespace="prod", deployment=~"prod-celery-beat-v1|prod-api-v1|prod-backend-v1"}
)
Upvotes: 1
Reputation: 17860
The filtering for this particular question can be done via the inner series selector before applying label_replace
. For example, the following query returns only series with class=~"BBBBB"
:
label_replace(
http_requests_total{handler=~"BBBBBController.*"},
"class",
"$1",
"handler",
"([a-zA-Z0-9]+)Controller.*"
)
P.S. While Prometheus doesn't provide the ability to post-filter time series by label values after they are selected by series selector, this can be done in VictoriaMetrics - Prometheus-like system I work on. See label_match and label_mismatch functions.
Upvotes: 5
Reputation: 21
I think the record rules feature might be helpful to you. Following is the steps for your reference
groups:
- name: http_requests_total_new_merics
rules:
- record: http_requests_total_new
expr: label_replace(http_requests_total, "class", "", "handler", "([a-zA-Z0-9]+)Controller.*")
then Prometheus will create new metrics named http_requests_total_new
Upvotes: 0
Reputation: 746
I've noticed that there is a grafana tag under this question, so if you don't mind to use grafana to achive that goal, then there is another way.
By using Grafana... 7.x+ IIRC, you can use Transform
to reprocess the raw result set.
For instance, I have a Query result like this:
Add a Filter data by values
plugin. You can set Match any
in it, and add a regex condition. Set field Class
matches BBBBB
or anything you want.
Upvotes: 1