kubernetesprometheuspromqlthanos

Aggregate 2 PromQL gauge metrics without including extra labels from right operand


Is it possible to aggregate 2 gauge metrics (i.e. kube_pod_labels and kube_pod_container_resource_requests_cpu_cores) so that by executing the query both resulting elements would be combined (i.e. all pod labels as resulting element and request_cpu_cores as value)?

Query for cpu request value looks like this sum by (namespace, pod) (kube_pod_container_resource_requests_cpu_cores{cluster="my-cluster"})

Actual result:

{namespace="my-ns",pod="my-pod"} 0.05

Query for pod labels is kube_pod_labels{label_foo="bar"}

Actual result:

kube_pod_labels{cluster="my-cluster",label_foo="bar",label_app="my-app-label",namespace="my-ns",pod="my-pod",service="my-svc"} 1

I have tried using a left joint but it seems that grouping by a given label (pod, namespace etc) is required as explained in this https://www.robustperception.io/left-joins-in-promql.

With a multiplication operator * is possible to obtain the desired result set but the set would only contain labels specified in the by clause. Example query:

group by (namespace,pod) (kube_pod_labels{label_foo="bar",cluster="my-cluster"}) * sum by (namespace, pod) (kube_pod_container_resource_requests_cpu_cores{cluster="my-cluster"})

Example result:

{namespace="my-ns",pod="my-pod"}    0.05

What I am trying to obtain is a resulting set containing all labels without having to filter by an arbitrary label/value

The desired result by joining the 2 queries should be:

{cluster="my-cluster",label_foo="bar", label_app="my-app-label",namespace="my-ns",pod="my-pod",service="my-svc"} 0.05

Solution

  • This can be achieved with a combination of the following:

    Example query:

    label_replace(kube_pod_labels{},"label","$1","label_", "(.+)") 
    * on (cluster,namespace, pod) group_left() 
    (sum by (cluster,namespace, pod) (kube_pod_container_resource_requests_cpu_cores{}))
    

    Note that: If the regular expression doesn't match then the timeseries is returned unchanged. In this case the regular expression does not match - hence the full set of labels is return unchanged.

    Example result:

    {cluster="my-cluster",label_foo="bar", label_app="my-app-label",namespace="my-ns",pod="my-pod",service="my-svc"} 0.05
    

    Felipe provided a valuable hint on how to achieve this result in a comment for the original question.