Prometheus is written in Go and uses RE2 and that does not support negative lookahead. From convenience perspective, its easier to write human-readable regex using that, but as its not supported, we’ll see a workaround for that.
Say for example, you have a label my_label
and you’d like to relabel all the label values to custom_value
where it contains my_value
but only when it does not contain foobar
.
If negative lookahead was supported, you could have written something like this:
- source_labels: [my_label]
regex: 'my_value(?!_foobar)'
target_label: my_label
replacement: 'custom_value'
So a matching metric would be:
my_metric{my_label="my_value"} -> my_metric{my_label="custom_value"}
And a non-matching metric would be:
my_metric{my_label="my_value_foobar_long_value"} -> my_metric{my_label="my_value_foobar_long_value"}
But since its not supported, you’ll get :
error parsing regexp: invalid or unsupported Perl syntax: `(?!`
Solution
What you can do is to specify the pattern with each possible suffix that you’d like to exclude.
So in our case, we’d like to exclude foobar
so the regex pattern would be:
regex: (my_value)_(?:[^f]|f[^o]|fo[^o]|foo[^b]|foob[^a]|fooba[^r]).*
Now, this is not as clean as negative lookahead, but this way works, and you can exclude any suffix you’d like, so the relabeling will work as expected.
- source_labels: [my_label]
regex: '(my_value)_(?:[^f]|f[^o]|fo[^o]|foo[^b]|foob[^a]|fooba[^r]).*'
target_label: my_label
replacement: 'custom_value'
You can test this relabeling using https://relabeler.promlabs.com. Here’s how it looks :
Possible Issues
- As we match each char, the relabeling will not work even if the label contains any char even if its just
foo
orfooba
etc as long as it starts withf
and ends withr
. So you’ll have to be careful with the regex pattern you write.