이 글은 아래 링크에 있는 것을 한글로 번역한 것입니다.
번역하게 된 이유는 prometheus 에서 relabel을 할 때 golang RE2에서 Negative Lookahead가 발생하는데 이를 해결하고자
한국어로 번역하여 기억해두기 위함입니다.
Prometheus는 Go로 작성되었고 RE2를 사용하며, 이는 부정형 전방탐색(negative lookahead)을 지원하지 않습니다. 편의성 측면에서는 사람이 읽기 쉬운 정규식을 작성하기에 좋지만, 지원되지 않기 때문에 이에 대한 우회 방법을 살펴보겠습니다.
예를 들어, my_label이라는 라벨이 있고, 해당 라벨 값에 my_value가 포함되어 있으면서 foobar는 포함되지 않은 경우에만 그 라벨 값을 custom_value로 변경(relabel)하고 싶다고 가정해봅시다.
만약 부정형 전방탐색이 지원되었다면, 다음과 같이 작성할 수 있었을 것입니다:
- source_labels: [my_label]
regex: 'my_value(?!_foobar)'
target_label: my_label
replacement: 'custom_value'
따라서 일치하는 메트릭은 다음과 같습니다:
my_metric{my_label="my_value"} -> my_metric{my_label="custom_value"}
그리고 일치하지 않는 메트릭은 다음과 같습니다:
my_metric{my_label="my_value_foobar_long_value"} -> my_metric{my_label="my_value_foobar_long_value"}
하지만,이것은 지원되지 않기에 다음과 같은 에러를 얻습니다:
error parsing regexp: invalid or unsupported Perl syntax: `(?!`
할 수 있는 방법은 제외하고 싶은 각 가능한 접미사를 포함하여 패턴을 지정하는 것입니다. 우리의 경우 foobar를 제외하고 싶기 때문에 정규식 패턴은 다음과 같이 됩니다:
regex: (my_value)_(?:[^f]|f[^o]|fo[^o]|foo[^b]|foob[^a]|fooba[^r]).*
물론 이 방법은 부정형 전방탐색만큼 깔끔하진 않지만, 이렇게 하면 원하는 접미사를 제외할 수 있으므로 리레이블링이 예상대로 작동합니다.
- 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'
relabeling 관련하여 이 사이트에서 테스트 가능하다. 그리고 아래는 그에 대한 테스트이다.


각 문자를 기준으로 일치시키기 때문에, 라벨에 어떤 문자가 포함되어 있어도 — 예를 들어 foo나 fooba처럼 — 시작이 f이고 끝이 r이면 리레이블링이 작동하지 않을 수 있습니다. 따라서 정규식 패턴을 작성할 때 주의가 필요합니다.