Skip to content

Native Metadata support in PromQL - #99

Open
roidelapluie wants to merge 2 commits into
prometheus:mainfrom
roidelapluie:roidelapluie/native-metadata-2
Open

roidelapluie wants to merge 2 commits into
prometheus:mainfrom
roidelapluie:roidelapluie/native-metadata-2

Conversation

@roidelapluie

Copy link
Copy Markdown
Member

No description provided.

Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com>
Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com>
Comment thread proposals/0099-promoting-promql-metadata.md
Comment thread proposals/0099-promoting-promql-metadata.md
Comment thread proposals/0099-promoting-promql-metadata.md

* Provide a non-conflicting way to query native metadata.
* Provide syntax that feels familiar to PromQL users.
* Be agnostic to the kind (namespace?) of metadata.

@krajorama krajorama Oct 6, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We settled on "category" in the native metadata design doc as namespace is too overloaded.

@krajorama krajorama left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

first pass, some technical comments - I'm doing a little research how this syntax fits with what's in the market


3. Native metadata are referenced as `~namespace.cpu.foo` or `~namespace."super+name"` (quoting follows the rules for label and metric names). An optional `~` can be added to prevent metadata promotion to the output. `~~namespace.cpu.foo`

4. Native metadata can be used to filter metrics when prefixed with `~`, in which case they are promoted as labels.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:

Suggested change
4. Native metadata can be used to filter metrics when prefixed with `~`, in which case they are promoted as labels.
4. Native metadata can be used to filter metrics when prefixed with `~`, in which case they are promoted as labels. The filter is combined with other native metadata and label filters as a logical AND (conjunction) operation. The order in which filters are evaluated is undefined and left to the implementation.

Metadata are only visible in query outputs once promoted, in which case they appear as labels.

Advantages: The query output format does not change, so tools that graph or display the results work without modification (provided they do not validate or need to understand the input syntax).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm missing a rule on what happens when the name of the native metadata conflicts with an existing label name. I think the rule should be that the label value wins and there is a warning level annotation. Also note that in this case the filtering on the label value is still applied and note that to get the value , the user needs to use as syntax.


`foo{~~resource.power.status="down"}`

`foo{~~resource[power.status]=~"down|stopped"}`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a leftover from proposal 97?

Suggested change
`foo{~~resource[power.status]=~"down|stopped"}`


`foo{~~resource[power.status]=~"down|stopped"}`

6. Native metadata can be aliased with the `as` keyword.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels like as should be introduced for labels as well, so maybe it should be in its own proposal?


`foo{~resource.power.status=~"down|stopped"}`

5. Native metadata can be used to filter metrics without being promoted as labels when prefixed with `~~`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the motivation for including and promoting native metadata is self evident, but let's add the motivation here: the use case is to be able to filter on native metadata that might change over time, but is not part of the series identity , e.g.:

request_total{~~power.status=~"starting|running"}

Would result in two different series on a graph if the mutable power.status changed over time.

@krajorama krajorama left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

another round


6. Native metadata can be aliased with the `as` keyword.

`foo and on (~resource.power.status as power_status) bar`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we'd want to specify what

foo and on (~resource.power.status) bar

means first. And I think it should mean that resource.power.status is filtered and promoted on both sides. That is this is 100% equivalent to:

foo{~resource.power.status=~".*"} and on(resource.power.status) bar{~resource.power.status=~".*"}

Making this a syntactic cookie. Should be possible to exclude from first PRs in implementation.
Note the use of * sign, which aligns with how on works for labels. If a label in on doesn't exist on both sides of the operator, those series match each other.

5. Native metadata can be used to filter metrics without being promoted as labels when prefixed with `~~`.

`foo{~~resource.power.status="down"}`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add the semantics of what happens when both ~ and ~~ is used:

foo{~resource.bar="x", ~~resource.bar="x"}
foo{~~resource.bar="x", ~resource.bar="x"}

I suggest that both mean that we filter on resource.bar , but we don't promote the native metadata to a label.

My motivation is that:

  • keep filter expressions commutative
  • I can image having wildcards later to say that I want to promote a set of metadata , like ~resource.k8s.pod.* , but want to hide some.

`foo{~~resource.power.status="down"}`

`foo{~~resource[power.status]=~"down|stopped"}`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also might be worth spelling out that

foo{~resource.bar=~".+"}

Means the native metadata must exist.

While

foo{~resource.bar=~".*"}

Mean the native metadata may exist or not. Same as labels.


`foo{~resource.power.status="down"}`

Example output: `foo{host="bar",resource.power.status="down"}`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the promoted attribute usable in the vector selector immediately? What does:

foo{~resource.bar=~".+", resource.bar="x"}

mean?

I think it should not be available immediately and I think the example should mean that we filter for non empty bar resource attribute and on the label resource.bar.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the spirit of the order of matchers not meaning anything , i.e. commutative.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or we error out at parsing and require as for at least one of them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants