8000 Relabeling: Using a labelname in a regex (to use the labelname's value) · Issue #11556 · prometheus/prometheus · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Relabeling: Using a labelname in a regex (to use the labelname's value) #11556

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
thernstig opened this issue Nov 9, 2022 · 13 comments · Fixed by #11564
Closed

Relabeling: Using a labelname in a regex (to use the labelname's value) #11556

thernstig opened this issue Nov 9, 2022 · 13 comments · Fixed by #11564

Comments

@thernstig
Copy link
thernstig commented Nov 9, 2022

Proposal

In relabeling config, let's say I have saved a value in a label like __tmp_port. I then want to match some port in Kubernetes service discovery

  relabel_configs:
    - source_labels: [ __meta_kubernetes_pod_container_port_number ]
      action: keep
      regex: ${__tmp_port}

If the value of __meta_kubernetes_pod_container_port_number and __tmp_port are both 8080, it will keep this target. It could possibly be used in replacement as well.

I would like to be able to use any existing __ value in the regex, even the ones found from service discovery such as __meta_kubernetes_pod_container_port_number.

It solves e.g. #3756

@juliusv
Copy link
Member
juliusv commented Nov 10, 2022

Since I'm reviewing #11564, I would like to understand a full use case example for this. Like, why would you put something into __tmp_port vs. just using a static value for the comparison? Referring to the linked issue, is it so you can compare an annotation label to a port label or something like that?

@thernstig
Copy link
Author
thernstig commented Nov 11, 2022

The usage of ${__tmp_port} was just to exemplify that I might have saved a port from a previous step. Here is an example:

metadata:
 annotations:            # containername:scheme:port:path:scrapespeed
   prometheus.io/scrape_1: "server:https:8585:/metrics:normal"
  relabel_configs:
    - source_labels: [ __meta_kubernetes_pod_annotation_prometheus_io_scrape_1 ]
      action: replace
      target_label: __tmp_port
      regex: "[^:]+:[^:]+:([^:]+):[^:]+:[^:]+" 
    - source_labels: [ __meta_kubernetes_pod_container_port_number ]
      action: keep
      regex: ${__tmp_port}

So you are correct in your assumption this was about "comparing an annotation label to a port label" in this case.

But I do think the functionality serves a good purpose for other use cases during service discovery.

@thernstig
Copy link
Author

Looking over the solution, it seems to solve this, but it is not as powerful as allowing __ labels to be used in regex as one then could do something.*${__tmp_port] (contrieved example, but it showcases that is more powerful to construct any kind of regex).

It would also keep the <relabel_action> options simpler.

@roidelapluie
Copy link
Member

@juliusv the issue is with service discoveries that expose multiple times the same target. I came up with a simple solution to the problem .

@juliusv
Copy link
Member
juliusv commented Nov 11, 2022

Thanks for the explanations, makes sense!

@thernstig is still suggesting to do something more general than the simple equality matching implemented in #11564. However, I'm not sure how we would implement that in a clean way. We can't just put something like ${...} into a Go regex because $ already has a specific regex meaning (match end of string) and introducing any other character or syntax to refer to a variable would also potentially break existing users. So unless I'm missing a good way to make that happen, I would also just go for the equality solution that @roidelapluie proposed.

@thernstig
Copy link
Author
thernstig commented Nov 11, 2022

@juliusv I think if you "premassage" the regex it could work. Search the regex for ${__identifier} from the list of all defined __ (loop through all __) and replace it in the regex.

I do not think it would be a breaking change as if someone already had the literal text ${__foo} in their regex, it would be an invalid regex. {} and its variants only support an integer inside it so ${...} in all forms would never mean repeat $ n amount of times or similar.

The only thing is that users might find it weird that special regex characters are used for something that is not actual regex functionality.

But with that said, I am fine with @roidelapluie approach as-is, even though I think it could be more powerful from the get-go.

@juliusv
Copy link
Member
juliusv commented Nov 11, 2022

Hmm yeah, that could work, although it is a tad weird as you say.

@roidelapluie Just checking to see what you think of @thernstig's proposal... but I'm fine either way :)

@roidelapluie
Copy link
Member
roidelapluie commented Nov 11, 2022

This would be incompatible with go regexes as you can have named capture groups.

@thernstig
Copy link
Author
thernstig commented Nov 11, 2022

@roidelapluie the capture groups are used in replacement. The proposal here is the look for it in regex and a regex does not have capture groups, it generates capture groups.

Again, with that said, I am fine with it as-is if that is preferred 😄

@roidelapluie
Copy link
Member
roidelapluie commented Nov 11, 2022

I think on general this would create a lot of corner cases and things difficult to do. What if a label contains a dot? It would be passed as a regex? And would not work like you would expect. ${__fqdn} replaced by example.com in regex would match example.com and example2com. And it's only one of the corner cases.

@thernstig
Copy link
Author
thernstig commented Nov 11, 2022

The pre-massaging could escape special characters. I do understand such an implementation would require quite a bit of work, so probably not worth it.

The main concern with my proposed solution is that users would be confused by using ${__something} in a regex. To understand that ${__something} is removed before the actual regex evaluation.

So your current solution works quite well as-is to solve many use cases and for me that is good enough.

@roidelapluie
Copy link
Member

Okay I'd say let's go with my proposal @juliusv

@juliusv
Copy link
Member
juliusv commented Nov 11, 2022

Yep, sounds good.

valyala added a commit to VictoriaMetrics/VictoriaMetrics that referenced this issue Dec 22, 2022
…ng actions

These actions are supported by Prometheus starting from v2.41.0

See prometheus/prometheus#11564 ,
prometheus/prometheus#11556
and prometheus/prometheus#3756

Side note:

It's a pity that Prometheus developers decided inventing `keepequal` and `dropequal`
relabeling actions instead of adding support for `keep_if_equal` and `drop_if_equal` relabeling
actions supported by VictoriaMetrics since June 2020 - see 2a39ba6 .
valyala added a commit to VictoriaMetrics/VictoriaMetrics that referenced this issue Dec 22, 2022
…ng actions

These actions are supported by Prometheus starting from v2.41.0

See prometheus/prometheus#11564 ,
prometheus/prometheus#11556
and prometheus/prometheus#3756

Side note:

It's a pity that Prometheus developers decided inventing `keepequal` and `dropequal`
relabeling actions instead of adding support for `keep_if_equal` and `drop_if_equal` relabeling
actions supported by VictoriaMetrics since June 2020 - see 2a39ba6 .
@prometheus prometheus locked as resolved and limited conversation to collaborators May 13, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants
0