JSON exporter
В составе Памир поставляется доработанная сборка json_exporter на основе версии 0.6.0. Отличия от
стандартной сборки:
- параметр запроса
cookie, а также хранение и переиспользование кук, полученных от целей; - jq-преобразования тела ответа перед выборкой значений;
- фильтр извлечённого значения регулярным выражением (
includeregex); - значения-даты превращаются в Unix-время;
- преобразование значений по таблице соответствий (
valueconverterстандартной сборки) не поддерживается.
Конфигурация экспортера хранится в Redis по ключу /exporters/json; при её изменении процесс экспортера
перезапускается. Экспортер слушает порт 7979:
| Путь | Назначение |
|---|---|
/probe | опрос цели — сюда обращается агент сбора метрик |
/metrics | метрики самого экспортера |
Параметры запроса
| Параметр | Обязательный | Допустимые значения | Если не передан |
|---|---|---|---|
target | да | URL цели вместе со схемой, например https://host:8161/api/queues | — |
module | нет | имя модуля из конфигурации экспортера | default |
cookie | нет | значение заголовка Cookie в формате имя=значение; имя2=значение2 | сохранённые куки этой цели |
| любой другой | нет | строка | — |
Произвольные параметры экспортер не проверяет: они доступны в шаблоне тела запроса, если в модуле включена
шаблонизация тела. В шаблоне параметр читается как список, поэтому берут его первый элемент — {{ .имя | first }}.
Приоритет параметров запроса и конфигурации
Параметрами запроса выбирается модуль и передаются куки, всё остальное берётся из конфигурации модуля: заголовки,
настройки HTTP-клиента и аутентификации, допустимые коды ответа, тело запроса. Переопределить эти настройки
параметрами запроса нельзя — можно только выбрать другой модуль параметром module.
Для кук порядок такой:
- параметр
cookie, если он передан и не пуст, — сохранённые куки в этом случае не подставляются; - куки, сохранённые от предыдущих ответов этой цели.
Если заголовок Cookie задан и в конфигурации модуля, и параметром cookie, в запросе уйдут два заголовка
Cookie — так делать не стоит, результат зависит от цели.
Куки
- После каждого успешного ответа — код ответа прошёл проверку модуля — экспортер запоминает куки из заголовков
Set-Cookie. - Хранилище находится в памяти процесса, ключ — хост и порт цели. Оно общее для всех модулей и заданий: следующий
запрос к тому же хосту и порту без параметра
cookieуйдёт с этими куками. - Новый ответ с
Set-Cookieзаменяет весь набор кук, сохранённый для хоста. Срок жизни куки не учитывается: она отправляется, пока её не заменит новая. - Хранилище очищается при перезапуске контейнера и при изменении конфигурации экспортера, поскольку конфигурация применяется перезапуском процесса.
- Отдельный запрос «на вход в систему» не нужен, если цель принимает аутентификацию из конфигурации модуля: первый же запрос вернёт куку сессии, а следующие запросы к этому хосту будут её переиспользовать.
Аутентификация
Способы перечислены в порядке предпочтения.
- Заголовок в конфигурации модуля. Заголовки модуля добавляются к каждому запросу, поэтому
Authorizationс готовыми учётными данными хранится в конфигурации экспортера и в URL не попадает. Если учётные данные различаются от цели к цели, заводится отдельный модуль на каждый набор, а нужный выбирается параметромmodule. - Настройки HTTP-клиента модуля (
http_client_config): базовая аутентификация, заголовок авторизации, OAuth2, параметры TLS и прокси. Набор полей — как у HTTP-клиента Prometheus. Соединения keep-alive и HTTP/2 экспортер отключает. - Учётные данные в URL цели —
https://user:password@host/api. Способ рабочий: если заголовкаAuthorizationнет, HTTP-клиент подставит из URL базовую аутентификацию. В продуктивной среде так делать не стоит: пароль оказывается в параметреtargetи виден в конфигурации таргета, в списке таргетов агента сбора метрик и в ответе источника таргетов. Заголовок из конфигурации модуля важнее: если он задан, учётные данные из URL не отправляются. - Секрет параметром задания, подставляемый в тело запроса через шаблонизацию тела. Ограничение то же, что и у предыдущего способа: значение видно в URL запроса к экспортеру.
jq-преобразования
Метрике можно задать цепочку преобразований тела ответа:
transformations:
- type: jq
query: '.result[] | {name: .name, health: .healthy}'
- Преобразование применяется ко всему телу ответа до выборки по JSONPath: путь метрики, её метки и значения считаются уже по результату преобразования.
- Результат — всегда массив из всех выдач фильтра, даже если выдача одна. Путь пишется соответственно:
{[*]}для перебора элементов,{[0].health}— для единственного значения. - Преобразования задаются отдельно для каждой метрики и применяются к исходному телу ответа, а не к результату преобразований соседней метрики.
- Если фильтр не выполнился, преобразование пропускается: метрика считается по данным до него, а в журнале
экспортера появляется сообщение
Transformation failed. - Поддерживается единственный тип преобразования —
jq. Конфигурация с другим типом не принимается: проверка конфигурации, которой пользуется механизм доставки конфигурации в контейнер, вернёт ошибку.
Прочие отличия от стандартной сборки
includeregexу метрики. Извлечённое значение фильтруется регулярным выражением, берётся первое совпадение. Работает только для метрик типаvalue. Если совпадения нет или выражение не компилируется, метрика пропускается, а причина пишется в журнал.- Значения-даты. Если значение не число и не логическое, экспортер пробует разобрать его как дату и записывает Unix-время в секундах. Дата без часового пояса читается как UTC.
- Регистр имён в конфигурации. Поля метрики разбираются в нижнем регистре:
epochtimestamp,includeregex,valuetype. Ключ, написанный иначе — напримерepochTimestamp, — молча игнорируется.
Неизвестные параметры и некорректные значения
| Ситуация | Ответ экспортера |
|---|---|
target не передан | 400, Target parameter is missing |
модуля нет в конфигурации, либо module не передан и модуля default в конфигурации нет | 400, Unknown module |
цель недоступна, код ответа не прошёл проверку модуля, target не разбирается как URL | 503, в теле — цель и текст ошибки; пароль в URL цели маскируется |
путь JSONPath не сработал, значение не приводится к числу, нет совпадения с includeregex, ошибка jq | ответ 200 без этой метрики, причина в журнале экспортера |
Неизвестные параметры запроса ошибкой не считаются. Если параметр передан несколько раз, используется первое значение.
Пример запроса
curl 'http://json-exporter:7979/probe?module=queues&target=https://broker.example:8161/api/queues'
Тот же запрос с явно переданной кукой — значение параметра кодируется как часть URL:
curl 'http://json-exporter:7979/probe?module=queues&target=https://broker.example:8161/api/queues&cookie=JSESSIONID%3D1a2b3c'
Настройка задания и relabel_configs
Конфигурация задания:
job_name: json
metrics_path: /probe
relabel_configs:
# URL цели из таргета — в параметр target
- source_labels: [__address__]
target_label: __param_target
# понятное имя таргета — в метку instance
- source_labels: [__name]
target_label: instance
# запрос уходит не на цель, а на экспортер
- target_label: __address__
replacement: json-exporter:7979
Шаблон таргета в метрике шаблона мониторинга:
- labels:
ci_id: '[[fields.ci_id]]'
__name: '[[fields.ci_name]]'
__param_module: queues
targets:
- 'https://[[attributes.instance]]/api/queues'
Правила выбора меток те же, что и у SNMP exporter: параметр доходит до
экспортера только через метку __param_<имя параметра>, значения меток — строки, один параметр задаётся одним
способом.
Безопасность
Всё, что передано параметрами запроса, видно в списке таргетов агента сбора метрик и в ответе источника таргетов,
а target вдобавок попадает в конфигурацию таргета целиком. Поэтому учётные данные держат в конфигурации
экспортера, а не в URL цели и не в параметрах запроса.
Экспортер не публикует свой порт за пределы сети Памир. Шифрование обращений к экспортеру описано в разделе SSL.