Ad Widget

Collapse

JSON как правильно считывать параметры

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Elis
    Member
    • Oct 2018
    • 71

    #1

    JSON как правильно считывать параметры

    Здравствуйте.

    Необходимо мониторить ресурсы приложения. У меня есть список выводимых параметров, доступных по http, в формате JSON.
    Я не знаю как zabbix агентом их считывать.


    Мои действия:

    - в zabbix_agent.conf указываю UserParameter=mediaJSON[*], 192.168.10.110:8554/sources/8/streams/0 $1
    - перезагружаю агента
    - добавляю метрику с ключом mediaJSON, с типом текст
    - получаю вот такую строку - ???⠪??᪠? ?訡?? ? ????? 䠩??, ????? ????? ??? ??⪥ ⮬?

    Где можно найти инструкцию, как выводить параметры JSON в zabbix.

    Спасибо за внимание. Очень нужна Ваша помощь


  • sadman
    Senior Member
    • Dec 2010
    • 1611

    #2
    Ну, как бы... Вы понимаете, что UserParameter оперирует исполняемыми файлами, а не бессмысленным набором цифр, букв и спецсимволов?

    Comment


    • Elis
      Elis commented
      Editing a comment
      теперь понимаю, спасибо
  • Elis
    Member
    • Oct 2018
    • 71

    #3
    кто пробовал для парсинга JSON использовать HTTP агент?

    Comment

    • sadman
      Senior Member
      • Dec 2010
      • 1611

      #4
      Подсказываю... curl, wget - исполняемые файлы, которые могут забрать JSON c HTTP и выкинуть его в stdout, который подхватит UserParameter и вернет серверу.

      Comment

      • Skamer
        Junior Member
        • Aug 2017
        • 8

        #5
        Всем привет. Не буду создавать новую тему, напишу в эту.
        Пытаюсь сделать опрос параметров жесткого диска на Win машинах.

        Используя smartmontools, вывожу список дисков и параметров для них в пользовательском параметре в виде json:
        Code:
        {"data":[
        {"{#HDD_NAME}":"/dev/sda"},
        {"{#HDD_NAME}":"/dev/sdb"},
        {"{#HDD_PARAM}":"name"},{"{#HDD_PARAM}":"model"},{"{#HDD_PARAM}":"serial"},{"{#HDD_PARAM}":"type"},{"{#HDD_PARAM}":"size"},{"{#HDD_PARAM}":"health"},
        {"software":"smartmontools"}]}
        Список дисков формируется автоматический, а вот параметры забил сам вручную, но не суть.
        В заббиксе настраиваю низкоуровневое обнаружение с фильтрами {#HDD_NAME} и {#HDD_PARAM}. Система почему-то выдает ошибку "Cannot accurately apply filter: no value received for macro "{#HDD_NAME}".", но это не мешает ей извлекать список дисков, видимо что-то с синтаксисом вывода списка...

        Добавляем далее пользовательский параметр с информацией о запрашиваемом диске:
        Code:
        {"data":{
        "name":"/dev/sda","model":"ST1000DM003-1ER162","serial":"Z4Y1S7B6","type":"3.5","size":"1,00 TB","health":"PASSED"
        }}
        Создаем прототип элемента данных с ключем hdd-discovery-info[{#HDD_NAME}] и делаем предобработку Путь JSON - $['data'][serial'] , и он нам выводит серийный номер на каждый диск. Так можно создать на каждый параметр вручную. Пути вида $.data[serial'] или $.data.serial почему-то не работают. Очень долго мучился с правильным написанием. Помог ресурс http://jsonpath.com/ .

        Но мне хотелось сделать, что бы параметры для диска выбирались макросом так же, как и имя диска, и я добавлял в предобработку параметр $['data']['{#HDD_PARAM}']. Он к сожалению не заработал.

        Возможно ли вообще получение данных с передачей макроса в предобработке данных JSON?

        Comment

        • Kos
          Senior Member
          Zabbix Certified SpecialistZabbix Certified Professional
          • Aug 2015
          • 3404

          #6
          Originally posted by Elis
          кто пробовал для парсинга JSON использовать HTTP агент?
          Если у вас версия 4.0, то можно использовать новый тип агента - HTTP Agent, с помощью которого забирать данные (ваш JSON) по HTTP(S), а потом разбирать полученное (парсить) с помощью препроцессинга.
          Получение данных и парсинг - разные этапы обработки, и на каждом из них используются свои средства.
          Last edited by Kos; 29-11-2018, 08:59.

          Comment

          • sadman
            Senior Member
            • Dec 2010
            • 1611

            #7
            Originally posted by Skamer
            Всем привет. Не буду создавать новую тему, напишу в эту.
            Code:
            {"data":[
            {"{#HDD_NAME}":"/dev/sda"},
            {"{#HDD_NAME}":"/dev/sdb"},
            {"{#HDD_PARAM}":"name"},{"{#HDD_PARAM}":"model"},{"{#HDD_PARAM}":"serial"},{"{#HDD_PARAM}":"type"},{"{#HDD_PARAM}":"size"},{"{#HDD_PARAM}":"health"},
            {"software":"smartmontools"}]}
            И куда такой JSON попадает? На месте препроцессора я бы тоже отказался его парсить - JSON-keys одинаковые, черт его знает как оттуда выборку делать.

            Comment

            • Skamer
              Junior Member
              • Aug 2017
              • 8

              #8
              Originally posted by Kos
              Если у вас версия 4.0, то можно использовать новый тип агента - HTTP Agent, с помощью которого забирать данные (ваш JSON) по HTTP(S), а потом разбирать полученное (парсить) с помощью препроцессинга.
              Получение данных и парсинг - разные этапы обработки, и на каждом из них используются свои средства.
              Я так понимаю, HTTP Agent забирает данные с http-сервера. Я же собираю данные с помощью windows-агента, выполняя .bat файл, который формирует данные в нужном мне виде.

              Originally posted by sadman
              И куда такой JSON попадает? На месте препроцессора я бы тоже отказался его парсить - JSON-keys одинаковые, черт его знает как оттуда выборку делать.
              С учетом ошибки, это все же работает. В узлы сети добавляются элементы данных из шаблона на каждый найденый диск. Подобный пример описан в документации, в конце страницы - https://www.zabbix.com/documentation...evel_discovery

              Comment

              • Kos
                Senior Member
                Zabbix Certified SpecialistZabbix Certified Professional
                • Aug 2015
                • 3404

                #9
                Originally posted by sadman
                И куда такой JSON попадает? На месте препроцессора я бы тоже отказался его парсить - JSON-keys одинаковые, черт его знает как оттуда выборку делать.
                Видимо, предполагалось использовать его для низкоуровневого обнаружения (LLD). Только тут в одном JSON-е смешаны два разных списка одновременно: и список жёстких дисков, и список параметров для мониторинга. Я тоже не очень понимаю, как автор вопроса предполагал, чтобы это работало.

                С учётом того, что бОльшая часть перечисленных им параметров - статичны (т.е. не меняются часто), и их нет смысла опрашивать часто, то я бы делал немного по-другому. А именно - засовывал бы эти параметры как значения соответствующих LLD-макросов, используя их для в прототипах для именования элементов данных и триггеров. А опрашивал бы только то, что реально может поменяться (в данном примере - параметр "health").

                Тогда нужный для LLD JSON мог бы иметь такой, например, вид:
                Code:
                {"data":[
                {"{#HDD_NAME}":"/dev/sda"},"{#HDD_MODEL}":"ST1000DM003-1ER162","{#HDD_SERIAL}":"Z4Y1S7B6","{#HDD_TYPE}":"3.5","{#HDD_SIZE}":"1,00 TB"},
                {"{#HDD_NAME}":"/dev/sdb"},"{#HDD_MODEL}":"ST0500DM003-1ER162","{#HDD_SERIAL}":"S76V3N0S","{#HDD_TYPE}":"3.5","{#HDD_SIZE}":"500 GB"}
                ]}
                Соответственно, прототип для единственного элемента данных мог бы выглядеть как-то так:
                Name: Health for {#HDD_NAME} ({#HDD_SIZE}, {#HDD_MODEL}, S/N:{#HDD_SERIAL}, Type:{#HDD_TYPE})
                Key: hdd.health[{#HDD_NAME}]
                Type of information: Character
                ...и т.д. по вкусу.

                Триггер - как-то так:
                Name: Disk {#HDD_NAME} ({#HDD_SIZE}, {#HDD_MODEL}, S/N:{#HDD_SERIAL}, Type:{#HDD_TYPE}) failed!
                Expression: {Hostname:hdd.health[{#HDD_NAME}].regexp("^PASSED$")}=0

                Ну и JSON, отдающий сами данные (в данном случае - только health) был бы проще. И нет необходимости подставлять LLD-макросы в правила парсинга.

                Originally posted by Skamer
                Я так понимаю, HTTP Agent забирает данные с http-сервера. Я же собираю данные с помощью windows-агента, выполняя .bat файл, который формирует данные в нужном мне виде.
                Это был мой ответ автору тему - Elis-у. Ваше письмо появилось, когда писал свой ответ. Я его подкорректировал, чтобы было видно, кому и на что я отвечаю.
                Last edited by Kos; 29-11-2018, 09:42.

                Comment

                • Skamer
                  Junior Member
                  • Aug 2017
                  • 8

                  #10
                  Originally posted by Kos
                  Видимо, предполагалось использовать его для низкоуровневого обнаружения (LLD). Только тут в одном JSON-е смешаны два разных списка одновременно: и список жёстких дисков, и список параметров для мониторинга. Я тоже не очень понимаю, как автор вопроса предполагал, чтобы это работало.

                  С учётом того, что бОльшая часть перечисленных им параметров - статичны (т.е. не меняются часто), и их нет смысла опрашивать часто, то я бы делал немного по-другому. А именно - засовывал бы эти параметры как значения соответствующих LLD-макросов, используя их для в прототипах для именования элементов данных и триггеров. А опрашивал бы только то, что реально может поменяться (в данном примере - параметр "health").

                  Тогда нужный для LLD JSON мог бы иметь такой, например, вид:
                  Code:
                  {"data":[
                  {"{#HDD_NAME}":"/dev/sda"},"{#HDD_MODEL}":"ST1000DM003-1ER162","{#HDD_SERIAL}":"Z4Y1S7B6","{#HDD_TYPE}":"3.5","{#HDD_SIZE}":"1,00 TB"},
                  {"{#HDD_NAME}":"/dev/sdb"},"{#HDD_MODEL}":"ST0500DM003-1ER162","{#HDD_SERIAL}":"S76V3N0S","{#HDD_TYPE}":"3.5","{#HDD_SIZE}":"500 GB"}
                  ]}
                  Соответственно, прототип для единственного элемента данных мог бы выглядеть как-то так:
                  Name: Health for {#HDD_NAME} ({#HDD_SIZE}, {#HDD_MODEL}, S/N:{#HDD_SERIAL}, Type:{#HDD_TYPE})
                  Key: hdd.health[{#HDD_NAME}]
                  Type of information: Character
                  ...и т.д. по вкусу.

                  Триггер - как-то так:
                  Name: Disk {#HDD_NAME} ({#HDD_SIZE}, {#HDD_MODEL}, S/N:{#HDD_SERIAL}, Type:{#HDD_TYPE}) failed!
                  Expression: {Hostname:hdd.health[{#HDD_NAME}].regexp("^PASSED$")}=0

                  Ну и JSON, отдающий сами данные (в данном случае - только health) был бы проще. И нет необходимости подставлять LLD-макросы в правила парсинга.
                  Конечно же я с вами согласен, что ошибки сами по себе не возникают, и здесь надо переделать это "по-человечьи".

                  Click image for larger version

Name:	1.jpg
Views:	714
Size:	99.2 KB
ID:	369849

                  Но в то же время даже в такой схеме я получаю данные

                  Click image for larger version

Name:	2.jpg
Views:	700
Size:	17.4 KB
ID:	369850

                  Click image for larger version

Name:	3.jpg
Views:	704
Size:	21.7 KB
ID:	369851

                  И да, опрос дисков я буду делать ну максимум раз в сутки, этого вполне будет достаточно.
                  Если я правильно понял предлагаемый Вами вариант, то он мне нравится больше. Я попробую реализовать его
                  Last edited by Skamer; 29-11-2018, 10:41.

                  Comment

                  • Elis
                    Member
                    • Oct 2018
                    • 71

                    #11
                    Originally posted by Kos

                    Если у вас версия 4.0, то можно использовать новый тип агента - HTTP Agent, с помощью которого забирать данные (ваш JSON) по HTTP(S), а потом разбирать полученное (парсить) с помощью препроцессинга.
                    Получение данных и парсинг - разные этапы обработки, и на каждом из них используются свои средства.
                    Спасибо, у меня теперь именно так и настроено, очень удобно пользоваться встроенными средствами zabbix, чем вызывать python скрипт, через user parametr.

                    Comment

                    • Skamer
                      Junior Member
                      • Aug 2017
                      • 8

                      #12
                      После некоторых мучений с освоением cmd и bat, сделал то что хотел.
                      Для желающих выкладываю результат:

                      Добавляем в конфиг агента:
                      Code:
                      UserParameter=hdd-discovery, C:\zabbix\smartmontools64\hdd-discovery.bat
                      UserParameter=hdd-health[*], C:\zabbix\smartmontools64\hdd-health.bat $1
                      Создаем правило низкоуровневого обнаружения:
                      Имя - HDD-discovery
                      Тип - Zabbix-агент
                      Ключ - hdd-discovery
                      Фильтр - {#HDD_NAME}

                      Создаем в этом правиле прототип элементов данных:
                      Имя -HDD {#HDD_NAME} {#HDD_VENDOR} {#HDD_MODEL} {#HDD_TYPE} {#HDD_SERIAL} {#HDD_SIZE} heath
                      Тип - Zabbix-агент
                      Ключ - hdd-health[{#HDD_NAME}]

                      Можно еще прототип триггеров:
                      Имя - HDD {#HDD_NAME} health
                      Выражение проблемы - {HDD.State:hdd-health[{#HDD_NAME}].str("FAILED!")}=1
                      Выражение восстановления - {HDD.State:hdd-health[{#HDD_NAME}].str("PASSED")}=1

                      Результат примерно такой:
                      Click image for larger version  Name:	hdd health.JPG Views:	1 Size:	49.8 KB ID:	370613


                      Текст программы hdd-discovery.bat
                      Code:
                      @echo off
                      Setlocal EnableDelayedExpansion
                      set "prg=C:\zabbix\smartmontools64\bin\smartctl.exe"
                      echo {"data":[
                      for /f %%a in ('%prg% --scan') do (
                      set "hddname=%%a"
                      set "hddvendor="
                      set "hddmodel="
                      set "hddtype="
                      set "hddserial="
                      set "hddsize="
                      for /f "tokens=2 delims=:" %%z in ('%prg% -i !hddname! ^| find "Model Family"') do for /F "tokens=* delims= " %%b In ('echo %%z') do set "hddvendor=%%b"
                      for /f "tokens=2 delims=:" %%y in ('%prg% -i !hddname! ^| find "Device Model"') do for /F "tokens=* delims= " %%c In ('echo %%y') do set "hddmodel=%%c"
                      for /f "tokens=2 delims=:" %%x in ('%prg% -i !hddname! ^| find "Form Factor"') do for /F "tokens=* delims= " %%d In ('echo %%x') do set "hddtype=%%d"
                      for /f "tokens=3" %%e in ('%prg% -i %%a ^| find "Serial Number"') do set "hddserial=%%e"
                      for /f "tokens=2 delims=[]" %%f in ('%prg% -i %%a ^| find "User Capacity"') do set "hddsize=%%f"
                      echo {"{#HDD_NAME}":"!hddname!","{#HDD_VENDOR}":"!hddvendor!","{#HDD_MODEL}":"!hddmodel!","{#HDD_TYPE}":"!hddtype!","{#HDD_SERIAL}":"s/n:!hddserial!","{#HDD_SIZE}":"!hddsize!"},
                      )
                      echo {"software":"smartmontools"}]}
                      Результат примерно такой:
                      Code:
                      {"data":[
                      {"{#HDD_NAME}":"/dev/sda","{#HDD_VENDOR}":"Seagate Barracuda 7200.14 (AF)","{#HDD_MODEL}":"ST1000DM003-1ER162","{#HDD_TYPE}":"3.5 inches","{#HDD_SERIAL}":"s/n:Z4Y1S7B6","{#HDD_SIZE}":"1,00 TB"},
                      {"{#HDD_NAME}":"/dev/sdb","{#HDD_VENDOR}":"Seagate Desktop HDD.15","{#HDD_MODEL}":"ST4000DM000-1F2168","{#HDD_TYPE}":"3.5 inches","{#HDD_SERIAL}":"s/n:Z300D821","{#HDD_SIZE}":"4,00 TB"},
                      {"{#HDD_NAME}":"/dev/sdc","{#HDD_VENDOR}":"Western Digital Black","{#HDD_MODEL}":"WDC WD5000BPKX-00HPJT0","{#HDD_TYPE}":"","{#HDD_SERIAL}":"s/n:WD-WX41AC3K4300","{#HDD_SIZE}":"500 GB"},
                      {"software":"smartmontools"}]}
                      Текст программы hdd-health.bat
                      Code:
                      @Echo Off
                      For /F "usebackq tokens=2 delims=:" %%z in (`C:\zabbix\smartmontools64\bin\smartctl.exe -H %~1 ^| find "test result"`)^
                      Do For /F "tokens=* delims= " %%a In ('echo %%z') Do echo %%a
                      Большое спасибо всем за помощь!

                      Comment

                      Working...