Продолжаю серию рассказов на тему настройки различных метрик в системе мониторинга заббикс. Сегодня расскажу, как быстро, легко и удобно передавать данные в json формате в zabbix и там их обрабатывать. Развитие функционала в последних версиях позволяют работать с json без лишних костылей и самописных скриптов.
На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.
Содержание:
Передача json данных в zabbix
Если у вас еще нет своего сервера для мониторинга, то рекомендую материалы на эту тему. Для тех, кто предпочитает систему CentOS:
То же самое на Debian 10, если предпочитаете его:
Для примера возьму мониторинг работы ноды Bitcoin. В данном случае это совершенно не принципиально, так как подход к парсингу json в zabbix одинаковый везде. Формат json сейчас очень популярен. Большое число сервисов его поддерживают для вывода информации или логов. У биткоин ноды есть команды для вывода информации о состоянии ноды. Вывод идет в формате json. Вот пример:
# bitcoin-cli getblockchaininfo
{ "chain": "test", "blocks": 1447503, "headers": 1447503, "bestblockhash": "506a6952d47b939e9d7baa34fc290b4356c446", "difficulty": 12691409.16925421, "mediantime": 1544607906, "verificationprogress": 0.9999915635029165, "initialblockdownload": false, "chainwork": "00000000000000000000000000db56207f5987ad3", "size_on_disk": 23159068639, "pruned": false, "softforks": [ { "id": "bip34", "version": 2, "reject": { "status": true } }, { "id": "bip66", "version": 3, "reject": { "status": true } }, { "id": "bip65", "version": 4, "reject": { "status": true } } ], "bip9_softforks": { "csv": { "status": "active", "startTime": 1456790400, "timeout": 1493596800, "since": 770112 }, "segwit": { "status": "active", "startTime": 1462060800, "timeout": 1493596800, "since": 834624 } }, "warnings": "Warning: unknown new rules activated (versionbit 28)" }
В своем примере я покажу, как из этого вывода парсить значения blocks и headers, хранить их в отдельных итемах в zabbix, чтобы дальше использовать в триггерах. По аналогии можно будет работать с другими значениями.
Настройка парсинга json в zabbix будет состоять из следующих шагов:
- Передаем всю json строку в исходном виде в итем в заббиксе.
- С помощью зависимых элементов данных формируем отдельные итемы с нужными значениями.
- Используем полученные итемы по назначению.
Для начала делаем простой скрипт для получения json - /etc/zabbix/scripts/getblockchaininfo.sh
#!/bin/bash /usr/bin/bitcoin-cli -rpcuser=user -rpcpassword=password -rpcport=8332 getblockchaininfo
Проверьте, что скрипт выдает корректную строку json. Далее создаем UserParameter. Я предпочитаю их хранить в разных конфигах, разделяя по функционалу. Создаю файл /etc/zabbix/zabbix_agentd.d/btc.conf следующего содержания:
UserParameter=blockchaininfo,/etc/zabbix/scripts/getblockchaininfo.sh
Сохраняем и перезапускаем zabbix-agent. Проверяем, что json корректно передается в нужном виде, без ошибок и прочих проблем:
# zabbix_agentd -t blockchaininfo
На выходе должны увидеть тот же самый json.
Zabbix агент подготовили. Для продолжения настройки, переходим на сервер.
Настройка zabbix server для мониторинга по json
На сервере создаем шаблон и добавляем в него элемент данных.
Подключите этот шаблон к хосту, где настраивали zabbix агент и подождите поступления данных. После того, как убедитесь, что json строка поступает на сервер, возвращайтесь в шаблон и создавайте еще один зависимый элемент данных.
В моем случае значение, которое я буду парсить из json, числовое, поэтому я выбираю соответствующий тип. У вас он может быть другой.
Дальше переходим на вкладку Preprocessing (предобработка):
В моем случае путь json очень простой. Если у вас более сложные выражения, то используйте удобный json парсер. Можете добавить туда свой json вывод и указать путь для парсинга, проверив таким образом его правильность.
Я убедился, что все верно. Сохраняем этот итем и ждем, когда он будет обработан. В latest data увидите значения из json строки.
По аналогии добавляете остальные элементы. Таким образом вы можете распарсить полностью json в отдельные итемы и использовать их дальше в триггерах и на графиках.
Заключение
Я показал простейший пример работы с json для тех, кто никогда не использовал его в zabbix. Благодаря тому, что в какой-то не очень давней версии появились зависимые элементы, работа с мониторингом сильно упростилась. Первое, что мне пришло в голову, когда нужно было выбрать отдельные значения из json вывода - написать баш скрипт. Это не сложно, я бы быстро распарсил и вытащил те данные, что мне нужны. Но вспомнив про зависимые элементы и возможность обработки данных в самом заббиксе, решил посмотреть в эту сторону и не ошибся. Так действительно проще и удобнее. За нас уже все сделали разработчики.
Скорее всего вам понадобится не просто парсинг json файла, но и автообнаружение на основе данных из него и автоматическое создание итемов. Но это уже тема отдельной статьи. А на сегодняшний момент это все, что я хотел рассказать, пока выдалась возможность поделиться информацией.
На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.
Подскажи пожалуйста, пытаюсь Json'ом забрать данные из большого списка, $.datа.datа1.("{HOST.NAME}").value и тут начинаются проблемы, заббикс не хочет подставлять вместо host.name имя хоста, а ищет значение HOST.NAME, но зато $.datа.datа1.("{$HOST}").value понимает и подставляет замечательно, писать на каждый хост макрос с заменой имени - как то не то, может быть подскажете решение проблемы?
Я не знаю, что посоветовать. Не использовал макросы в предобработке. Я так понимаю, макрос {HOST.NAME} это глобальный, а {$HOST} - настроен вручную для хоста?
Добрый день! Да, пришлось писать макрос для каждого хоста отдельно, только таким образом получилось добиться правильной работы, это довольно сильно усложнило работу и увеличило риск появления ошибок. Странно, что такой функционал не заложен в среде заббикс (либо я не нашел способа его реализации), везде глобальные макросы работали без проблем, а тут нет. Спасибо за ответ
Подскажите пожалуйста. Есть железка с api. прежде чем получить основную информацию, необходимо авторизовать и получить токен. Получилось заббиксом получить токен авторизации, но никак не могу сообразить как его использовать при следующем запросе?
Тут могут быть варианты реализации. Я решал эту задачу так. Получал токен скриптом и через API заббикса передавал его в макрос шаблона или конкретного хоста. А этот макрос использовал в айтеме для получения данных, передавая токен в заголовке запроса.
Подскажите, в чем причина использования дополнительного (зависимого) item-а, если обработку можно было сделать сразу?
Основной айтем берётся за базу, как источник всей информации. Для него можно указать очень маленькое время хранения, так как информации в нём много и большая часть не нужна. А с базового айтема можно сделать много зависимых, в которых будет храниться только нужная информация. И её можно хранить намного дольше, так как объём там минимальный. Обычно один айтем — одна метрика. Это вопрос удобства и оптимизации.
Пытаюсь прикрутить к Proxmox Mail Gateway мониторинг, чтобы сделать триггер на спам-атаку. Но JSON лес дремучий. Так и не понял, что и куда делать.
Как вообще получать эти данные с PMG?
Я не настраивал никогда мониторинг PMG, так что не подскажу. Даже не смотрел никогда, как он там устроен в плане мониторинга.
Есть API документация для PMG https://pmg.proxmox.com/pmg-docs/api-viewer/index.html
Проблема в том, что не понимаю, что нужно делать. Ужа полтора часа курю мануалы, но в голове пусто
а как распарсить каждый конкретный id? как в примере. не могу понять как выводить разные id в разные итемы.
Добрый день
Помогите решить проблему, не могу запарсить HTTP запрос
получаю строку
{"body":{"StatusSNS":{"Time":"1970-01-02T00:44:42","AM2301":{"Temperature":31,"Humidity":36.9,"DewPoint":15},"TempUnit":"C"}}}
дальше создаю зависимый элемент данных и в проработке использую JSONPatch
$.body.StatusSNS.AM2301.Temperature
но выдаёт, ошибку мол:
cannot extract value from json by path "$.body.StatusSNS.AM2301.Temperature":
Хотя если разобрать запрос через jsonpath.com, патч отрабатывает нормально
в чём затык, подскажите пожалуйста?
заранее благодарен!!!
Попробуйте так:
$[]body[]StatusSNS[]AM2301[]Temperature
Я сталкивался с подобными моментами. Парсер Zabbix немного не совпадает с jsonpath.com.
нее, так же(( ругается
cannot extract value from json by path "$[]body[]StatusSNS[]AM2301[]Temperature": unsupported construct in jsonpath starting with: "]body[]StatusSNS[]AM2301[]Temperature"
всё же заработало с $.body.StatusSNS.AM2301.Temperature, пересоздал зависимый элемент
тест так же с ошибкой, но данные поползли)
спасибо)
Подозреваю, что ранее при проверке где-то была ошибка:
unsupported construct in jsonpath starting with: "]body[]StatusSNS[]AM2301[]Temperature"
Строка начинается не с $ - "]body[]StatusSNS[]AM2301[]Temperature"
У меня заработало так:
```yaml
zabbix_export:
version: '6.0'
groups:
- uuid: 02951830a9e6474d9a00168e11171d3a
name: 'Linux servers'
templates:
- uuid: 58879fdd49a64c9399626a20309620e1
template: StatusSNS
name: StatusSNS
description: https://serveradmin.ru/parsing-i-peredacha-json-dannyih-v-zabbix/
groups:
- name: 'Linux servers'
items:
- uuid: 4b5a260e98fc408a9a4eb6d39eb28c1f
name: AAA
key: aaa
delay: 15s
trends: '0'
value_type: TEXT
- uuid: baecd4fbe6454177b24dfce61c11e1d2
name: 'AAA BBB'
type: DEPENDENT
key: body.StatusSNS.AM2301.Temperature
trends: '0'
value_type: TEXT
preprocessing:
- type: JSONPATH
parameters:
- $.body.StatusSNS.AM2301.Temperature
master_item:
key: aaa
```
Блин. Тут код нельзя прикреплять! АРРР!!!
https://pastebin.com/wJsn2rtQ
Здравствуйте ! Спасибо за статью!
Пытаюсь передать данные из ES через агента на сервер. Агент не может запустить скрипт *.sh. При выполнении тестовой команды агента, в консоли выскакивает сообщение "отказано в доступе". Я агента уже из под root запустил и владельца файла менял. Картина та-же. Может подскажете, в чем может быть проблема ?
В ES есть api. Зачем тут zabbix-agent и скрипты? Забирайте данные сразу же http агентом с сервера. Примеры в статьях можно посмотреть:
https://serveradmin.ru/rabota-s-api-yandeks-metriki-v-zabbix/
https://serveradmin.ru/monitoring-chisla-podpischikov-kanala-telegram-v-zabbix/
https://serveradmin.ru/ustanovka-nastrojka-i-monitoring-nody-zcash/#__zcash
[
{
"ID": 28574,
"Username": "XXXXX",
"Groupname": "XXXX",
"State": "connected",
"Device": "vpns1",
"MTU": "1406",
"Remote IP": "XXXXX",
"Location": "Russian Federation",
"Local Device IP": "XXXXXX",
"IPv4": "XXXXX",
"P-t-P IPv4": "XXXXX",
"User-Agent": "Cisco AnyConnect VPN Agent for Android 4.8.03651 / samsung SM-A",
"RX": "0",
"TX": "496",
"Restricted to routes": "False",
"Restricted to ports": []
}
]
Пытался сделать по мануалу
прилетает такое на сервер
но вычленить не могу.. $.Username
Если бы прилетало без квадратных скобок - то работало бы.. в чем затык?
Затык в том, что скобки надо убрать в предобработке. Например, вот так - https://serveradmin.ru/wp-content/uploads/2020/09/zabbix-google-api-14.png
Спасибо!!!! тогда дополните в основной текст!! ))))
Так это частности. Чистый json не надо дополнительно обрабатывать.
И еще вопрос как за экранировать пробел в ключе правильно
"Remote IP": "XXXXX",
Что значит заэкранировать и для чего? Вы же в заббиксе парсите строку, которая уже пришла.
$."(Remote \IP)" не работает
$.Remote IP
cannot extract value from json by path "$.Remote IP": unsupported construct in jsonpath starting with: " IP"
Увы!!
$.['Remote IP'] это рабочий вариант
на всякий случай
Спасибо.
Подскажите пожалуйста, как можно http_agent заставить забирать данные у Java-приложения, с логином через j_security_check.
У меня выходит что:
шаги вебсценария я могу прописать для логина, и получить нужный мне стринг со странички, но больше кода или стринга - я не получаю.
А в случае с айтемом типа http_agent и препроцессингом - все могу, но не могу себя авторизовать, и соответственно забрать и обработать json.
Я не разбирался с авторизацией в http агенте, так что не смогу подсказать. Обычно получается так или иначе ему напрямую отдать данные, без авторизации.
Я в результате плюнул и забираю все курл-скриптом
Тоже вариант, почему нет, если так быстрее и проще. Неудобно только разворачивать и хранить. Когда делаешь через http агент, все сохраняется в шаблоне и легко переносится. Но если надо сделать один раз, то я обычно делаю максимально быстро и просто.
Добрый день.Спасибо за статью.А можете подсказать как будет выглядеть автообнаружение на основе данных из него и автоматическое создание итемов. А то не совсем получается.
Вот тут есть пример автообнаружения - https://serveradmin.ru/monitoring-bekapov-s-pomoshhyu-zabbix/#i-4
Скрипт backup-discovery.sh
Ну и в целом пример построен с использованием автообнаружения.
Спасибо посмотрел.Но интересует если json такой вид и как при этом создавать автообнаружения и ITEM
{ "data": [
{
"{#Name}": "System Idle Process",
"{#WorkingSet}": 8192
},
{
"{#Name}": "chrome.exe",
"{#WorkingSet}": 3296219136
}
]}
Подскажите как решить момент с тем потоком данных что идут по основному ключу? они же бд засирают сильно
Настроить минимальное время хранения, если эти данные не нужны.
Здравствуйте. Не могли бы вы показать как осуществить передачу json данных в Zabbix с помощью http агента?
Не пробовал еще работать с http агентом.
Не могу найти информацию как это правильно сделать.
С HTTP агентом почти то же самое, что и Zabbix agent, только в JSONPath необходимо к ключам добавлять $.body. - так как мы парсим страницу (body) в RAW и потом конвертим в JSON (почему-то в чистом JSON у меня не получилось извлекать данные по HTTP)
Как вы решали вопрос с авторизацией?
Не понял, в данном случае забикс и битчейнода должны стоять на одном сервере?
Нет. Данные можно забирать с любого сервера, где установлен агент заббикса, если сама служба позволяет удаленный запрос json данных. В данном случае у меня на серверах везде стоит агент, поэтому я собирал локально. Но если бы агента не было, я бы через удаленные запросы забирал json с какого-нибудь другого сервера.