Вопрос или проблема
Мы мигрируем нашу мониторинговую инфраструктуру на Prometheus. Мы используем prometheus-sd-exporter для Netbox для генерации http_sd_config для получения данных. Из-за того, как узлы были названы в нашем экземпляре Netbox, сгенерированная __address__
метка не содержит FQDN, что не сработает для получения данных в нашем случае. Сгенерированная __address__
метка выглядит так:
__address__="host:9182"
У нас есть пользовательское поле, содержащее FQDN, __meta_netbox_custom_field_vm_dns
, и я могу переназначить __address__
, конкатенируя сгенерированную плагином __address__
метку с полем FQDN:
- source_labels: [__address__]
regex: '.*([^:]\d\d\d+$).*'
replacement: '$1'
action: replace
target_label: __tmp_port
- source_labels: [__meta_netbox_custom_field_vm_dns, __tmp_port]
separator: ':'
target_label: __address__
Однако этот regex (который работает) смущает меня, так как я не понимаю, почему он нуждается в \d\d\d
– исходя из этого regex, я думаю, что должен быть в состоянии получить номер порта без них. Я пробовал несколько итераций этого:
regex: '([^:]+$)' (даёт http://host.example.com/metrics)
regex: '([^:]+$).*' (даёт http://host.example.com/metrics)
regex: '.*([^:]+$)' (даёт http://host.example.com:2/metrics)
regex: '.*([^:]+$).*' (даёт http://host.example.com:2/metrics)
regex: '.*([^:]\d+$).*' (даёт http://host.example.com:82/metrics)
regex: '.*([^:]\d\d+$).*' (даёт http://host.example.com:182/metrics)
regex: '.*([^:]\d\d\d+$).*' (даёт http://host.example.com:9182/metrics, что является правильным значением)
Мне интересно, есть ли что-то, что я делаю неправильно в процессе переназначения/regex, так как мы хотели бы, чтобы это работало для произвольного номера порта, а не для номера, состоящего ровно из четырех цифр.
У кого-нибудь есть идеи, почему это ведёт себя таким образом или что-то, что я мог бы сделать иначе?
Спасибо!
Ответ или решение
Понимание релейбелинга в Prometheus с использованием регулярных выражений
При переходе на мониторинг с использованием Prometheus важно правильно настроить релейбелинг метрик для корректного сбора данных. В вашем случае, вы используете балансировщик prometheus-sd-exporter
для Netbox, который генерирует конфигурацию http_sd_config
. Однако полученные метки не содержат полного доменного имени (FQDN), что затрудняет процесс опроса.
Проблематика
Исходный формат метки __address__
выглядит следующим образом:
__address__="host:9182"
Здесь, как видно, часть с FQDN отсутствует. Ваша задача заключается в объединении метки __address__
с пользовательским полем __meta_netbox_custom_field_vm_dns
, содержащим FQDN.
Решение с использованием релейбелинга
Вы правильно определили последовательность действий, чтобы изменить метку __address__
, используя механизм релейбелинга Prometheus:
- source_labels: [__address__]
regex: '.*([^:]\d\d\d+$).*'
replacement: '$1'
action: replace
target_label: __tmp_port
- source_labels: [__meta_netbox_custom_field_vm_dns, __tmp_port]
separator: ':'
target_label: __address__
Однако ваше недоумение связано с использованием шаблонов регулярного выражения, в частности с необходимостью использования \d\d\d
.
Разбор регулярного выражения
Давайте внимательно проанализируем ваше регулярное выражение:
.*
— соответствует любым символам (ноль или более раз).([^:]\d\d\d+$)
— здесь используется группа для захвата, которая ищет последовательность цифр, за которой следует конец строки.
Ваши попытки без использования \d
приводят к тому, что регулярное выражение начинает искать несоответствующие строки. Например, выражение ([^:]+$)
может захватить все, что идет после двоеточия, включая FQDN, но неразрывно и без конкретизации порта.
Использование \d\d\d
в изначальном регулярном выражении фиксирует минимальную границу для порта, что в вашем случае необходимо для корректного выделения нужной строки. Таким образом, ваше выражение в значительной степени зависит от специфики форматов портов, с которыми вы работаете.
Альтернативное решение
Чтобы сделать вашу логику более универсальной и адаптивной к различным портам, вы можете изменить регулярное выражение на более общее:
- source_labels: [__address__]
regex: '.*:([^:]+)$'
replacement: '$1'
action: replace
target_label: __tmp_port
Этот вариант будет соответствовать любой последовательности после двоеточия, что позволяет обрабатывать порты любой длины:
.*:
— ищет любой текст перед двоеточием.([^:]+)$
— захватывает символы после двоеточия до конца строки, что обеспечивает максимальную гибкость.
Заключение
В заключение, релейбелинг и использование регулярных выражений в Prometheus могут вызывать определенные трудности, особенно когда речь идет о портах. Понимание и точная настройка регулярных выражений являются критически важными для правильного сбора метрик. Применение приведенного здесь альтернативного решения позволит вам без труда обрабатывать порты любой длины, а также упростит процесс масштабирования вашей мониторинга в будущем.