Zabbix Prometheus

Материал из noname.com.ua
Перейти к навигацииПерейти к поиску


Использование экспортеров Prometheus в Zabbix

Начиная с версии 4.2 Zabbix поддерживает работу с экспортерами Prometheus
Строго говоря это обычные HTTP метрики однако работать с ними стало более-менее удобно. Эта заметка появилась в связи с недостатком документации

Замечание

Возможно что снимать метрики JMX в условиях интернет можно более эффективно используя нативные средства Zabbix, такие как Zabbix Proxy но этак гипотеза мной не проверялась,

Постановка задачи

  • Существует приложение на Java с включенным экспортом JMX-метрик (как включить экспорт см тут: !!!! )
  • Требуется снимать метрики JMX в Zabbix
  • Метрики динамические (например время чтения из keyspace, имена которых заранее неизвестны), что требует Autodiscovery
  • Доступ к интерфейсу JMX приложения осуществляется через интернет (задержки до 100мс)

Вероятно из-за задержек при значительном (~1000) числе метрик часть данных начинала теряться, причем заранее предсказать какая именно метрика будет потеряна нельзя. Все попытки решить проблему настройками Zabbix Java Gateway (увеличение числа потоков/Heap Size/Разные версии Gateway) к успеху не привели


Суть решения в том что вместо того что б делать медленный запрос со 100мс задержкой на каждый объект JMX, локальный экспортер делает те же запросы через localhost c ~0 RTT и отдает в ответ по HTTP все метрик в одном запросе. Дальнейший разбор метрик происходит уже на стороне Zabbix

Prometheus Exporter

Введение в Prometheus Exporter

Prometheus использует отдельные процессы-экспортеры для сбора данных которые запускаются на хостах, и отдают данные по запросу (pull модель) по протоколу http (подробное описание Prometheus выходит за рамки этой заметки)

Для решения задачи предпологается:

  • на каждом хосте с JVM запустить JMX Exporter (https://github.com/prometheus/jmx_exporter)
    • Экспортер может работать как standalone HTTP сервер, те опрашивать приложение и отдавать метрики по HTTP
    • Может встраиваться как агент (этот вариант я не могу использовать так как встраивание на-лету доступно только с 9-й Java а перезапуск приложений для меня недопустим)
  • Со стороны Zabbix настраивается сбор метрик по HTTP


Настройка Prometheus JMX Exporter

Сборка

mvn package 

или скачать готовый jar file Для запуска standalone server потребуется (с точностью до версии):

jmx_prometheus_httpserver-0.11.1-SNAPSHOT-jar-with-dependencies.jar


Конфигурация

systemd unit file

Потенциально может быть запущено несколько экземпляров экспортера, потому я подготовил юнит с поддержкой экземпляров:
/etc/systemd/system/prometheus-exporter@.service

[Unit]
Description=Prometeus Exporter:  %i
After=network.target

[Service]
PIDFile=/var/run/prometheus-exporter.%i.pid
Type=simple
EnvironmentFile=/etc/prometheus-exporter/prometheus-exporter
EnvironmentFile=/etc/prometheus-exporter/%i/env

ExecStart=/usr/bin/java \
                -jar ${JAR_FILE} \
                ${BIND_ADDR}:${BIND_PORT} \
                /etc/prometheus-exporter/%i/config.yaml


SuccessExitStatus=0 143


[Install]
WantedBy=multi-user.target
  • /etc/prometheus-exporter/prometheus-exporter Переменные общие для всех экземпляров
  • /etc/prometheus-exporter/%i/env Переменные специфичные для экземпляра


Переменные окружения общие для всех инстансов

/etc/prometheus-exporter/prometheus-exporter

JAVA="/usr/bin/java"
JAR_FILE="/usr/share/jmx_exporter/jmx_prometheus_httpserver-0.11.1-SNAPSHOT-jar-with-dependencies.jar"

Пояснений не требует

Переменные окружения специфичные для инстанса

Пример для сервиса /cassandra-localhost /etc/prometheus-exporter/cassandra-localhost/env

BIND_ADDR="0.0.0.0"
BIND_PORT="65001"

BIND_ADDR / BIND_PORT - адрес и порт на котором запускать HTTP сервер с метриками



Конфигурация JMX Exporter

---
hostPort: localhost:7199
username:
password:

#lowercaseOutputLabelNames: true
#lowercaseOutputName: true
whitelistObjectNames:
  - "java.lang:type=GarbageCollector,*"
  - "java.lang:type=MemoryPool,*"
  - "java.lang:type=Memory,*"
  - "java.lang:type=ClassLoading,*"
  - "java.lang:type=Compilation,*"
  - "java.lang:type=MemoryManager,*"
  - "java.lang:type=OperatingSystem,*"
  - "java.lang:type=Runtime,*"
  - "java.lang:type=Threading,*"
  - "org.apache.cassandra.metrics:type=*,scope=*,*"


# ColumnFamily is an alias for Table metrics
blacklistObjectNames:
  - "org.apache.cassandra.metrics:type=ColumnFamily,*"
  - "org.apache.cassandra.metrics:type=Table,keyspace=system_auth,*"
  - "org.apache.cassandra.metrics:type=Table,keyspace=system,*"
  - "org.apache.cassandra.metrics:type=Table,keyspace=*,scope=*,name=BloomFilter,*"

rules:
- pattern: "java.lang<type=GarbageCollector, name=(.+)><>(.+):"
  name: java.lang_GC
  type: UNTYPED
  labels:
    "gc_name":     "$1"
    "metric_name": "$2"
... skipped...

Конфигурационный файл более-менее подробно описан на странице prometheus-exporter, повторю кратко

  • hostPort: localhost:7199 Адрес и порт приложения с JMX. В общем случае JMX Exporter может быть запущен и на другом хосте, особенно в случае локальной сети или одной zone для клаудов, когда RTT между хостами невелико. В примере указан localhost - мониторится приложение запущенное на том же хосте что и exporter на порту 7199 - Cassandra
  • username / password Логин/Пароль если JMX настроен с авторизацией, в примере не используется
  • whitelistObjectNames: Белый список объектов
    • "java.lang:type=GarbageCollector,*" Пример объекта который нужно мониторить - метрики сборщика мусора JVM
    • "org.apache.cassandra.metrics:type=*,scope=*,*" Еще один объект для мониторинга
  • blacklistObjectNames: Черный список (перекрывает белый список если нужно добавить исключение)
    • "org.apache.cassandra.metrics:type=ColumnFamily,*"

В каком виде отдать метрики задает секция rules

  • rules: Начало секции
  • pattern: "java.lang<type=GarbageCollector, name=(.+)><>(.+):" Паттерн определяет какие части метрики использовать - в примере первое выражение (.+) определит имя коллектора а второе - имя метрики (или скорее тип) например CollectionCount или CollectionTime
  • name: java.lang_GC Имя метрики как она будет видна в http- ответе
  • type: UNTYPED Тип метрики (уточнить но скорее всего не важен для zabbix)
  • labels: Метки которые будут установлены на метрику
    • "gc_name": "$1" $1 соответствует первому (.+)
    • "metric_name": "$2" $1 соответствует второму (.+)


Вывод http выглядит так

curl 127.0.0.1:65001 2>/dev/null | grep -v '#'  | grep java_lang_GC

java_lang_GC{gc_name="G1 Young Generation",metric_name="CollectionCount",} 6091.0
java_lang_GC{gc_name="G1 Young Generation",metric_name="CollectionTime",} 1360730.0
java_lang_GC{gc_name="G1 Young Generation",metric_name="Valid",} 1.0
java_lang_GC{gc_name="G1 Old Generation",metric_name="CollectionCount",} 0.0
java_lang_GC{gc_name="G1 Old Generation",metric_name="CollectionTime",} 0.0
java_lang_GC{gc_name="G1 Old Generation",metric_name="Valid",} 1.0

Полный конфиг приведен в конце статьи

Zabbix

В версии 4.2 появилась работа с Prometheus Exporter
Добавить создание всех объектов через Zabbix API - конфигурирование руками подходит только для небольших установок

Предварительная конфигурация

В текущих версиях нет возможности указать дополнительные интерфейсы вроде JMX и ссылаться на них в темплейте, приходится использовать Host Macros

Z-001 Screen Shot .png

Для того что бы добавить макросы к хосту

1 - Конфигурация 2 - Раздел Hosts, выбрать нужный хост 3 - Раздел макросы

Макросы которые я использую

{$PROMETEUS_EXPORTER_ADDR_0}
{$PROMETEUS_EXPORTER_PORT_0}

Обратить внимание на формат именования макросов хостов - это "{$ИМЯ_МАКРОСА}" в отличие от {#ИМЯ_МАКРОСА} в правилах автообнаружения.
Индекс _0 добавлен для поддержки будущих экспортеров, если такие будут

Создание шаблона

Все элементы добавляются к шаблону, подробно о шаблонах написано в документации Zabbix

Simple Item

Первый шаг - получить все данные
На этом простом элементе будут базироваться остальные элементы
По сути это обычный элемент данных HTTP

Z-002.png

Единственное отличие - то что адрес для подключения читается из макроса хоста

{$PROMETEUS_EXPORTER_ADDR_0}:{$PROMETEUS_EXPORTER_PORT_0}

Z-003.png
Остальные настройки (которые не попали на скриншот) оставлены по-умолчанию

Данные при нормальной работе выглядят примерно так (начало, показаны не все метрики)

# HELP jmx_config_reload_success_total Number of times configuration have successfully been reloaded.
# TYPE jmx_config_reload_success_total counter
jmx_config_reload_success_total 77.0
# HELP cassandra_Table_ReadRepairRequests_count Attribute exposed for management (org.apache.cassandra.metrics<type=Table, keyspace=KEYSPACE_NAME, scope=SCOPE_NAME, name=ReadRepairRequests><>Count)
# TYPE cassandra_Table_ReadRepairRequests_count untyped
cassandra_Table_ReadRepairRequests_count{Table="TABLE_NAME",keyspace="KEYSPACE_NAME",} 0.0
cassandra_Table_ReadRepairRequests_count{Table="TABLE_NAME",keyspace="KEYSPACE_NAME",} 13.0


Z-004.png

Discovery Rule

Все дальнейшие действия производятся с данными из базовой метрики, в том числе и процедура дискавери


Создаем Discovery Rule


Правило базируется на уже существуюшум элементе данных
Z-005.png

Processing

В разделе Processing указать правило - какие именно метрики собирать
Z-006.png
Тут важно обратить внимание на 2 момента

  • Указать тип - преобразование в JSON
  • Правильно указать способ преобразования

Например полученные данные выглядят так:

curl 127.0.0.1:65001 2>/dev/null | grep -v '#'  | grep java_lang_GC
java_lang_GC{gc_name="G1 Young Generation",metric_name="CollectionCount",} 6091.0
java_lang_GC{gc_name="G1 Young Generation",metric_name="CollectionTime",} 1360730.0
java_lang_GC{gc_name="G1 Young Generation",metric_name="Valid",} 1.0
java_lang_GC{gc_name="G1 Old Generation",metric_name="CollectionCount",} 0.0
java_lang_GC{gc_name="G1 Old Generation",metric_name="CollectionTime",} 0.0
java_lang_GC{gc_name="G1 Old Generation",metric_name="Valid",} 1.0


Правило процессинга

java_lang_GC{metric_name=~".*", gc_name=~".*"}

говорит о том что надо выделить метки (labels - они определяются в конфигурации экспортера)
Пример ответа можно посмотреть здесь: https://www.zabbix.com/documentation/4.2/manual/discovery/low_level_discovery/prometheus?s[]=prometheus
но для версии 4.2 тест сломан (баг заведен) и реально посмотреть не получится
По сути будет заполнена структура labels, для примера примерно так:

        "labels": {
            "metric_name="CollectionCount",
            "gc_name": "G1 Young Generation"
         }, 

Макросы

Данные из этой структуры можно извлечь в макросы: Z-007.png

Z-008.png

Z-009.png

Z-010.png

Z-011.png

Item Prototype

Задача - мониторить абстрактное приложение написанное на Java в Zabbix