Search code examples
prometheusgrafanapromql

Grafana table from Prometheus metric with key-value labels


I have a metadata metric in Prometheus that looks like this

# HELP metadata Process metadata
# TYPE metadata counter
metadata{hostname="server-a",key="version",value="v1.1.0"} 1
metadata{hostname="server-a",key="feature1",value="true"} 1
metadata{hostname="server-a",key="feature2",value="false"} 1
metadata{hostname="server-b",key="version",value="v1.0.0"} 1
metadata{hostname="server-b",key="feature1",value="false"} 1

where the key label has the name of the field and the value label has a string value. We don't care about the value of the metric, but it'll always be 1.

Is it possible to have Grafana format this as a table? i.e. like this

Hostname version feature1 feature2
server-a v1.1.0 true false
server-b v1.0.0 false

If I have a separate query (with Table format) for each possible key then I'm able to make it look like that with two transformations: an Outer join by hostname, then a Organize fields to remove the excess fields.

However, I'd like to do that without a separate query for each key, or even hardcoding key if possible. But despite all my fiddling with transforms I can't figure out how. There's also a couple of questions here that ask about similar things, but none of them do exactly what I'm looking for:

And a few things that don't work

  • A single query for metadata{} in table format has a column for the key and a column for the value, rather than column with the name of the key
  • Closest I've gotten is with a Time series query then a Label to fields transformation, which has a column of 1s whose name is the value of key.

So is what I want even possible in Grafana?


Solution

  • With the new Grouping to Matrix transform introduced by this PR in Grafana v8.5.0, this is now possible!

    • Set the Prometheus query to have Format: Table and Type: Instant.

    • Add a Grouping to Matrix Transform, with:

      • Column: key ("I want a different column for each key")
      • Row: hostname ("I want a different row for each hostname")
      • Value: value ("The cell should take the value from value")
      • Empty Value: both Null or Empty will produce the correct output
    • Add a Rename by regex Transform.

      • Match: (.*)\\.*
      • Replace: $1

      The Grouping to Matrix transform produces a column with name like <row>\<column> (e.g. hostname/\key), and this fixes that to be just the row name (e.g. hostname)

    • Finally, set the Visualisation (top right) to Table.