Scott Numamoto

With Clauses in MetricsQL

I find that writing queries on metrics from data sources that I don’t have much control over can become quite complex and difficult to read. This gets even harder when I’m trying to debug a misbehaving query that returns no data.

Since I’m using VictoriaMetrics rather than Prometheus, my queries are in MetricsQL. MetricsQL is like PromQL but comes with extra usability features, like with clauses.

Let’s say I’m trying to get the percent memory utilization of a container with metrics from kube-state-metrics.

sum(container_memory_working_set_bytes{pod="my-pod", container="my-container"})
/
sum(kube_pod_container_resource_limits{resource="memory", unit="byte", pod="my-pod", container="my-container"})

Instead of repeating the same filters all over the place, we can pull them into a with clause. Now, if I need to fiddle with pod or container, I only have to do it once.

with (
    filters = {pod="my-pod", container="my-container"},
)

sum(container_memory_working_set_bytes{filters})
/
sum(kube_pod_container_resource_limits{resource="memory", unit="byte", filters})

I’ve found using with clauses as variables useful for self-documenting expressions.

with (
    filters = {pod="my-pod", container="my-container"},
    utilized_memory = sum(container_memory_working_set_bytes{filters}),
    memory_limit = sum(kube_pod_container_resource_limits{resource="memory", unit="byte", filters}),
)

utilized_memory
/
memory_limit

If we found ourselves repeating this pattern in multiple places, we could define a function. This is probably overkill for most use cases, but it’s nice to know that MetricsQL offers functions and sub-with clauses.

with (
  percent_utilized_memory(filters) = 
    with (
      utilized_memory = sum(container_memory_working_set_bytes{filters}),
      memory_limit = sum(kube_pod_container_resource_limits{resource="memory", unit="byte", filters}),
    ) 

    utilized_memory 
    / 
    memory_limit
  ,
)

percent_utilized_memory({pod="my-pod", container="my-container"})

If you find yourself getting lost in your queries with VictoriaMetrics, try out a with clause!