Парсинг и передача json данных в Zabbix

Продолжаю серию рассказов на тему настройки различных метрик в системе мониторинга заббикс. Сегодня расскажу, как быстро, легко и удобно передавать данные в json формате в zabbix и там их обрабатывать. Развитие функционала в последних версиях позволяют работать с json без лишних костылей и самописных скриптов.

Онлайн-курс по устройству компьютерных сетей

На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.

Передача json данных в zabbix

Если у вас еще нет своего сервера для мониторинга, то рекомендую материалы на эту тему. Для тех, кто предпочитает систему CentOS:

  1. Установка CentOS 8.
  2. Настройка CentOS 8.
  3. Установка и настройка zabbix сервера.

То же самое на Debian 10, если предпочитаете его:

  1. Установка Debian 10.
  2. Базовая настройка Debian.
  3. Установка и настройка zabbix на debian.

Для примера возьму мониторинг работы ноды 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 будет состоять из следующих шагов:

  1. Передаем всю json строку в исходном виде в итем в заббиксе.
  2. С помощью зависимых элементов данных формируем отдельные итемы с нужными значениями.
  3. Используем полученные итемы по назначению.

Для начала делаем простой скрипт для получения 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.

Пример json данных

Zabbix агент подготовили. Для продолжения настройки, переходим на сервер.

Настройка zabbix server для мониторинга по json

На сервере создаем шаблон и добавляем в него элемент данных.

Итем для передачи json в zabbix

Подключите этот шаблон к хосту, где настраивали zabbix агент и подождите поступления данных. После того, как убедитесь, что json строка поступает на сервер, возвращайтесь в шаблон и создавайте еще один зависимый элемент данных.

Парсинг json строки в зависимый элемент данных

В моем случае значение, которое я буду парсить из json, числовое, поэтому я выбираю соответствующий тип. У вас он может быть другой.

Дальше переходим на вкладку Preprocessing (предобработка):

Параметры обработки json

В моем случае путь json очень простой. Если у вас более сложные выражения, то используйте удобный json парсер. Можете добавить туда свой json вывод и указать путь для парсинга, проверив таким образом его правильность.

JSON парсер

Я убедился, что все верно. Сохраняем этот итем и ждем, когда он будет обработан. В latest data увидите значения из json строки.

Проверка мониторинга данных через парсинг json

По аналогии добавляете остальные элементы. Таким образом вы можете распарсить полностью json в отдельные итемы и использовать их дальше в триггерах и на графиках.

Заключение

Не понравилась статья и хочешь научить меня администрировать? Пожалуйста, я люблю учиться. Комментарии в твоем распоряжении. Расскажи, как сделать правильно!

Я показал простейший пример работы с json для тех, кто никогда не использовал его в zabbix. Благодаря тому, что в какой-то не очень давней версии появились зависимые элементы, работа с мониторингом сильно упростилась. Первое, что мне пришло в голову, когда нужно было выбрать отдельные значения из json вывода - написать баш скрипт. Это не сложно, я бы быстро распарсил и вытащил те данные, что мне нужны. Но вспомнив про зависимые элементы и возможность обработки данных в самом заббиксе, решил посмотреть в эту сторону и не ошибся. Так действительно проще и удобнее. За нас уже все сделали разработчики.

Скорее всего вам понадобится не просто парсинг json файла, но и автообнаружение на основе данных из него и автоматическое создание итемов. Но это уже тема отдельной статьи. А на сегодняшний момент это все, что я хотел рассказать, пока выдалась возможность поделиться информацией.

Онлайн-курс по устройству компьютерных сетей.

На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.

Помогла статья? Подписывайся на telegram канал автора

Анонсы всех статей, плюс много другой полезной и интересной информации, которая не попадает на сайт.

Автор Zerox

Владимир, системный администратор, автор сайта. Люблю настраивать сервера, изучать что-то новое, делиться знаниями, писать интересные и полезные статьи. Открыт к диалогу и сотрудничеству. Если вам интересно узнать обо мне побольше, то можете послушать интервью. Запись на моем канале - https://t.me/srv_admin/425 или на сайте в контактах.

47 комментариев

  1. Николай

    Подскажи пожалуйста, пытаюсь Json'ом забрать данные из большого списка, $.datа.datа1.("{HOST.NAME}").value и тут начинаются проблемы, заббикс не хочет подставлять вместо host.name имя хоста, а ищет значение HOST.NAME, но зато $.datа.datа1.("{$HOST}").value понимает и подставляет замечательно, писать на каждый хост макрос с заменой имени - как то не то, может быть подскажете решение проблемы?

    • Я не знаю, что посоветовать. Не использовал макросы в предобработке. Я так понимаю, макрос {HOST.NAME} это глобальный, а {$HOST} - настроен вручную для хоста?

      • Николай

        Добрый день! Да, пришлось писать макрос для каждого хоста отдельно, только таким образом получилось добиться правильной работы, это довольно сильно усложнило работу и увеличило риск появления ошибок. Странно, что такой функционал не заложен в среде заббикс (либо я не нашел способа его реализации), везде глобальные макросы работали без проблем, а тут нет. Спасибо за ответ

  2. Подскажите пожалуйста. Есть железка с api. прежде чем получить основную информацию, необходимо авторизовать и получить токен. Получилось заббиксом получить токен авторизации, но никак не могу сообразить как его использовать при следующем запросе?

    • Тут могут быть варианты реализации. Я решал эту задачу так. Получал токен скриптом и через API заббикса передавал его в макрос шаблона или конкретного хоста. А этот макрос использовал в айтеме для получения данных, передавая токен в заголовке запроса.

  3. Алексей

    Подскажите, в чем причина использования дополнительного (зависимого) item-а, если обработку можно было сделать сразу?

    • Основной айтем берётся за базу, как источник всей информации. Для него можно указать очень маленькое время хранения, так как информации в нём много и большая часть не нужна. А с базового айтема можно сделать много зависимых, в которых будет храниться только нужная информация. И её можно хранить намного дольше, так как объём там минимальный. Обычно один айтем — одна метрика. Это вопрос удобства и оптимизации.

  4. Андрей

    Пытаюсь прикрутить к Proxmox Mail Gateway мониторинг, чтобы сделать триггер на спам-атаку. Но JSON лес дремучий. Так и не понял, что и куда делать.
    Как вообще получать эти данные с PMG?

  5. а как распарсить каждый конкретный id? как в примере. не могу понять как выводить разные id в разные итемы.

  6. Добрый день

    Помогите решить проблему, не могу запарсить 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
      ```

  7. Андрей

    Здравствуйте ! Спасибо за статью!
    Пытаюсь передать данные из ES через агента на сервер. Агент не может запустить скрипт *.sh. При выполнении тестовой команды агента, в консоли выскакивает сообщение "отказано в доступе". Я агента уже из под root запустил и владельца файла менял. Картина та-же. Может подскажете, в чем может быть проблема ?

  8. [
    {
    "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
    Если бы прилетало без квадратных скобок - то работало бы.. в чем затык?

  9. Подскажите пожалуйста, как можно http_agent заставить забирать данные у Java-приложения, с логином через j_security_check.
    У меня выходит что:
    шаги вебсценария я могу прописать для логина, и получить нужный мне стринг со странички, но больше кода или стринга - я не получаю.

    А в случае с айтемом типа http_agent и препроцессингом - все могу, но не могу себя авторизовать, и соответственно забрать и обработать json.

    • Я не разбирался с авторизацией в http агенте, так что не смогу подсказать. Обычно получается так или иначе ему напрямую отдать данные, без авторизации.

      • Я в результате плюнул и забираю все курл-скриптом

        • Тоже вариант, почему нет, если так быстрее и проще. Неудобно только разворачивать и хранить. Когда делаешь через http агент, все сохраняется в шаблоне и легко переносится. Но если надо сделать один раз, то я обычно делаю максимально быстро и просто.

  10. Александр

    Добрый день.Спасибо за статью.А можете подсказать как будет выглядеть автообнаружение на основе данных из него и автоматическое создание итемов. А то не совсем получается.

    • Вот тут есть пример автообнаружения - 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
        }
        ]}

  11. Подскажите как решить момент с тем потоком данных что идут по основному ключу? они же бд засирают сильно

  12. Руслан

    Здравствуйте. Не могли бы вы показать как осуществить передачу json данных в Zabbix с помощью http агента?

    • Не пробовал еще работать с http агентом.

    • С HTTP агентом почти то же самое, что и Zabbix agent, только в JSONPath необходимо к ключам добавлять $.body. - так как мы парсим страницу (body) в RAW и потом конвертим в JSON (почему-то в чистом JSON у меня не получилось извлекать данные по HTTP)

  13. Евгений

    Не понял, в данном случае забикс и битчейнода должны стоять на одном сервере?

    • Нет. Данные можно забирать с любого сервера, где установлен агент заббикса, если сама служба позволяет удаленный запрос json данных. В данном случае у меня на серверах везде стоит агент, поэтому я собирал локально. Но если бы агента не было, я бы через удаленные запросы забирал json с какого-нибудь другого сервера.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Нажимая кнопку "Отправить комментарий" Я даю согласие на обработку персональных данных.
Используешь Telegram? Подпишись на канал автора →
This is default text for notification bar