Вступ
- some.thing.here[one:two:three][foo=x,bar=y]
- Як це працює
- Що реалізовано
- Collector
- Використання
- Discoverer
- Використання
- Приклад налаштування вузлів у Zabbix
- Синтаксис ключів
- Значення Simple
- Значення Aggregated
- Приклади
- Агреговані значення
- Low level discovery
- Приклади айтема прототипу
- Приклад connections
- Приклад для nodes
- Підіб'ємо підсумок
& nbsp & nbsp & nbsp & nbspЗіткнувшись із завданням замоніторити велике кол-во метрик в RabbitMQ кластері, з'явилося бажання створити універсальний парсер для JSON даних. Завдання ускладнювалося тим, що з'являються і пропадають метрики динамічно під час роботи кластера, плюс до цього розробники постійно хочуть зібрати/порахувати щось нове. На жаль, у Zabbix немає можливості збирати дані в такому вигляді з коробки. Але є така зручна фіча як zabbix_trapper, що дозволяє робити гнучку кастомізацію. У статті піде мова про не сосвем стандартний спосіб використання айтемів zabbix_trapper. Мені не хотілося кожен раз, коли розробники попросять додати нових метрик, змінювати скрипт, який збирає дані і засилає в заббікс. Звідси з'явилася ідея використовувати власне сам zabbix key як інструкцію зі збору нової метрики. Суть в наступному, ми використовуємо zabbix key як команду, з заздалегідь заданим синтакісом. Тобто zabbix key в цьому випадку буде служити інструкцією, подібною до ключів типу zabbix_agent.
Згідно з офіційною документацією Zabbix, item key має деякі обмеження на допустимі символи. Трохи перегравши з створенням ключів типу zabbix trapper знайшов, що наприклад ключ виду:
some.thing.here[one:two:three][foo=x,bar=y]
створюються в заббіксі без помилок. Тобто обмеження працюють тільки на те, що поза [] дужок, також обов'язково повинен бути хоча б один символ [a-z] [A-Z] перед дужками. Маючи можливість створювати такі ключі ми можемо придумати свій синтаксис ключів і запрограмувати в ньому досить гнучку логіку. Далі залишається тільки написати обробник придуманого синтаксису який буде робити всю основну роботу. І нарешті, написавши доку по цьому обробнику і виклавши код в паблік, у всього Zabbix community з'явиться можливість обмінюватися такими «як би» плагінами.
& nbsp & nbsp & nbsp; загалом стаття вийшла трохи складною для розуміння, тому щоб краще зрозуміти концепцію, я б радив спочатку ознайомитися з RabbitMQ API, хоча б просто подивитися як виглядають дані і що надає API (див. офф сайт).
& nbsp; & nbsp; & nbsp; & nbspup;
Як це працює
& nbsp & nbsp & nbsp; Спочатку створюємо в Zabbix фронт-енді айтеми типу zabbix_trapper згідно з розробленим синтаксисом (синтксис буде описаний нижче). Далі запускаємо обробник (rmq_data_collect.pl - далі колектор) в кроні з частотою збору інформації, скажімо 1 хвилина. Тепер колектор взаємодіє з Zabbix сервером і з сервером RabbitMQ як вказано на схемі:
Тобто. скрипт робить 3 основних кроки:
1) Запитує список айтемів з Zabbix сервера, які слід зібрати.
2) Забирає всі необхідні дані з RabbitMQ згідно зі списком айтемів вище.
3) Надсилає всі зібрані дані на Zabbix сервер/проксі на співвідв-і айтеми.
& nbsp & nbsp & nbsp & nbspp; При першому збаченні обробник може взаємодіяти як через Zabbix API так і безпосередньо з базою. У моїй реалзації взаємодія відбувається з базою Zabbix проксі. Цей підхід зручніше при використанні розподіленого моніторингу з деяким кол-вом Zabbix проксі серверів. У цьому випадку скрипт повинен бути встановлений на zabbix проксі сервері, а в конфігурації скрипту повинні бути прописані дані для коннекту до бази цієї ж проксі.
& nbsp & nbsp & nbsp; Крім обробника буде також розглянуто дискаверер, який використовується для low level discovery. Далі піде мова про поточну реалізацію моніторингу для RabbitMQ, теорія та приклади налаштування.
Що реалізовано
& nbsp & nbsp & nbsp & nbspB документації по RabbitMQ API описано 9 API url'ів + є ще federation-links, який ставиться окремим плагіном на реббіт. Можливо є і ще щось. У поточній реалізації моїх скриптів можливий моніторинг таких API path:
-nodes
-connections
-queues
-bindings
-federation-links
Для моїх завдань цього вистачило, у разі якщо потрібні ще якісь API path то потрібно дописати їх у ф-ю map_rmq_elements (див. коментарі до коду).
Встановлення та налаштування скриптів
& nbsp & nbsp & nbsp; Для моніторингу RabbitMQ знадобиться встановити і налаштувати 2 скрипти (Collector і Discoverer) + ZabbixProxyDB.pm. Скрипти можуть бути встановлені як на Zabbix сервері так і на проксі, залежить від вашої конфігурації Zabbix.
Collector
rmq_data_collect.pl - Використовується для обробки заббікс ключів і збирання даних з rabbitmq.
Використання
Має один вхідний параметр
$1 - повна назва RabbitMQ вузла в Zabbix, якщо RabbitMQ не запущено як кластер. У разі якщо реббіт працює як кластер, $1 - це загальна частина імені хостів у кластері, тобто імена хостів у класері повинні бути задані за певним правилом. Наприклад імена хостів у кластері:
— rmq-host1
— rmq-host2
— rmq-host3
& nbsp & nbsp & nbsp & nbspB цей випадок має бути "rmq-host" ". Скрипт запросить у Zabbix сервера/проксі список всіх хостів з іменами, що містять «rmq-host», після чого піде за цим списком, запитуючи необхідні дані до RabbitMQ API. Після першої успішної відповіді від будь-якого з вузлів дані будуть зібрані і записані в файл для відправки zabbix_sender'ом. На момент написання статті є недопрацювання в коді, у разі якщо не один хост з кластера RabbitMQ не відповість то нічого не станеться. У поточній реалізації вимоги до імен хостів пов'язані з SQL запитом до бази, поки тільки так.
& nbsp & nbsp & nbsp; має бути прописаний у crontab з частотою збирання даних з реббіта. Список необхідних додатків можна переглянути в самому скрипті.
Discoverer
rmq_data_discover.pl - Використовується для низькорівневого виявлення в Zabbix (low level discovery або LLD).
Використання
Має 3 обов'язкові вхідні параметри:
$1 - повна назва RabbitMQ вузла в Zabbix, якщо RabbitMQ не запущено як кластер. Для кластера принцип той же що у колектора. Після першої успішної відповіді проходження за списком зупиниться і почнеться компіляція повідомлення для низькорівневого виявлення (low level discovery).
$2 - regexp за яким відбудеться відбір метрик у момент роботи скрипту. Не плутати з regexp фільтром на боці Заббікс у налаштуваннях LLD. Такий поділ зручний у деяких випадках.
$3 - RabbitMQ API path, будь-який зі списку підтримуваних (див. п. Що реалізовано).
& nbsp; & nbsp & nbsp; має бути встановлений у теці externalscripts, прописаній у налаштуванні Zabbix проксі/сервера. Приклади налаштування правил LLD наведено наприкінці статті.
Приклад налаштування вузлів у Zabbix
& nbsp; & nbsp; & nbsp; кластер rabbitmq, що складається з трьох вузлів. Самі хости окремо моніторяться заббікс агентами, темплейт Template_Linux, де зібрані стандартні метрики по CPU, memory і т. д. Для метрик кластера створено окремий хост «rmq-host». Ім'я хоста для всього кластера - загальна частина імен хостів у кластері. Ця обов'язкова умова в поточній реалізації, інакше вибірка з бази буде працювати не коректно.
Синтаксис ключів
Тепер поговоримо про розроблений мною синтаксис для реббіту. Як вже було сказано вище, в Zabbix айтеми повинні мати тип zabbix trapper.
Для моніторингу реббіта Є два типи item'ів, simple і aggregated, їх синтаксис незначно відрізняється. Simple айтеми використовуються для вибору значень окремих параметрів. Aggregated айтеми використовуються для вибору масиву значень за заданою умовою і їх агрегації. В обох випадках умови може бути не вказано (опціонально).
Значення Simple
Синтаксис: <path.to.value.inside.json>[$type:$api_path:$element_name]
< path.to.value.inside.json > - Шлях до значення всередині кожного елемента масиву.
$ type - може бути назва VHOST або «general», у випадку VHOST пошук значень буде вестися за вказаним VHOST, «general» - є ключовим словом, необхідним для значень, які не належать до конкретних VHOST'ам.
$ api _ path - RabbitMQ API path, будь-який з підтримуваних (див. п. Що реалізовано).
$ element _ name - це унікальний ідентифікатор елемента масиву в вказаному $ api _ path, для federation-links це exchange, для bindings це destination, для інших name.
Значення Aggregated
Загальний синтаксис: <path.to.value.inside.json|rmq>[aggregated:$api_path:$func][$conditions]
aggregated - є ключовим словом, після якого збірка (rmq_data_collect.pl) розуміє, що синтаксис ключа повинен бути розібраний як для значення типу aggregated.
$ api _ path - шлях до API, будь-який з підтримуваних (див. п. Що реалізовано).
$ func - реалізовано 2 функції, sum і count.
$ conditions - це опціональний параметр, якщо позначено цей пункт, при агрегації будуть враховуватися лише ті елементи у масиві даних, які підходять під умову. Синтаксис умов наступний: [condition1=“cond1”,condition2=“cond2”,condition3=“cond3”,etc]. Лапки обов'язкові. Сама умова є Perl регекспом.
Функція sum
Синтаксис: <path.to.value.inside.json>[aggregated:$api_path:sum][$conditions]
Функція sum підсумовує значення, що знаходяться за вказаним шляхом < path.to.value.inside.json > всередині кожного елемента масиву, отриманого за $ api _ path, і підходить під умову $ conditions.
< path.to.value.inside.json > - Шлях до значення всередині кожного елемента масиву отриманого за RabbitMQ API path.
Функція count
Синтаксис: rmq[aggregated:$api_path:count][$conditions]
Функція count вважає кол-во елементів у масиві, отриманому за $ api _ path, що підходять під умову.
rmq - є обов'язковим словом, але ніяк не використовується (тут може бути абсолютно будь-який набір букв). Це пов'язано з обмеженнями Zabbix на ключ айтема типу «zabbix_trapper» - айтем не може починатися з квадратної дужки.
Приклади
Агреговані значення
1) Рахує суму елементів running в масиві nodes. Прим: У разі якщо rabbitmq нода працює, running повертає 1, соот-но на виході отримуємо кол-во працюючих нод.
2) Рахує кол-во елементів у масиві queues, де name = ^ system-queue1 $. Оскільки значення умови завжди розглядається як regexp необхідно задавати початок і кінець рядка (^ $) щоб уникнути помилки у випадку, якщо під regexp потрапить щось ще. На виході отримуємо кол-во черг з ім'ям system-queues1
3) Вважає загальне кол-во елементів в масиві nodes. Тобто. кол-во налаштованих нод у класетері.
4) Вважає загальне кол-во елементів в масиві connections. Тобто. кол-во сполук до кластеру в даний момент.
5) Вважає кол-во елементів у масиві connections, у яких type = « direct $» і protocol = « Direct\s0-9-1 $».
Приклади для значень simple є далі в LLD. Оскільки задавати їх статично не зручно, більшість черг постійно з'являються і зникають.
Low level discovery
У слуачаї великої конфігурації rabbitmq кластера розумно буде використовувати низькорівневе виявлення Zabbix. Використання rmq_data_discover.pl описано вище. Тут я наведу приклади і значення, які повертається скриптом.
Значення, які повертаються скриптом і які можна використовувати в LLD:
Connections
{#VHOST}"" => $vhost,
{#NAME}"" => $name,
{#NODE}"" => $node,
Nodes
{#NODENAME}"" => $name,
Bindings
{#SOURCE}"" => $queueSource,
{#VHOST}"" => $vhost,
{#DESTINATION}"" => $queueDest,
{#THRESHOLD}"" => $threshold,
Зауваження: всі елементи з порожнім source ігноруються.
Queues
{#VHOST}"" => $vhost,
{#QUEUE}"" => $queueName,
Federations
“{#VHOST”} => $vhost,
“{#EXCHANGE} => $name
Приклади LLD
Приклади запуску правил для кожного API path:
Приклади айтема прототипу
В API path queues ми можемо збирати статистику за обробленими повідомленнями, не піклуючись про кол-ві черг.
1) Значення поля idle_since. Єдине поле яке має обробку всередині rmq_data_collector.pl. Як результат отримуємо timestamp, з моменту якого черга неактивна.
2) Значення ack всередині елемента message_stats.
3) Решта значень працюють з message_stats також як п.2
Приклад connections
Айтем підраховує кол-во елементів в масиві connections з заданими type, protocol для кожного {# VHOST}.
Приклад для nodes
1) Вважає кол-во з'єднань до кожної ноди.
2) Повертає значення поля running для кожного елемента масиву nodes. На виході отримуємо health статус кожної ноди.
Підіб'ємо підсумок
& nbsp & nbsp & nbsp & nbspСподіваюся вийшло не надто заплутано. Якщо щось не зрозуміло, відповім на всі питання в коментарях.
& nbsp & nbsp & nbsp & nbspПеревага описаного підходу у створенні кастомних ключів, спеціалізованих для якогось конкретного софта, очевидно. Немає необхідності у зміні коду самого Zabbix. Вже зараз ми можемо створювати такі плагіни, писати по них документацію і обмінюватися готовими рішеннями в інтернеті. Якщо розвивати ідею створення кастомізованих ключів у Zabbix далі, то в ідеалі хотілося б бачити це, можливо, у вигляді нової фічі. Маючи подібний плагін тепер, коли потрібно додати какуюто нову метрику по RabbitMQ, потрібно просто створити співвідв-ий айтем, як це робиться для zabbix_agent.
& nbsp & nbsp & nbsp & nbspКод скриптів тут: github.com/mfocuz/zabbix_plugins





