Ad Widget

Collapse

Парсинг JSON через Правила обнаружения. Не передаются данные прототипам.

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Tonik
    Junior Member
    • Jun 2023
    • 13

    #1

    Парсинг JSON через Правила обнаружения. Не передаются данные прототипам.

    Добрый день. Необходимо мониторить RAID-контроллер Adaptec.
    План: Получить информацию об логических дисках и на каждый найденный лог. диск автоматически создавать элемент данных, в котором будет его состояние (Optimal, Degraded и т.д.).

    Информацию об логических дисках на контроллере можно получить через CMD отправив команду: arcconf getconfig 1 LD.

    1) Создаю элемент данных:
    Имя: Discovered LD​
    Тип: Zabbix агент
    Ключ: system.run["arcconf getconfig 1 LD"]
    Тип информации: Текст
    Предобработка: JavaScript
    Code:
    const ld = value.match(/number.(.*)/g);
    const status = value.match(/logical.device.*:.(.*)/g);
    var data = [];
    for (i = 0; i <= ld.length; i++) {
        data.push({"LD": ld[i], "Status": status[i]});
    }
    data.pop();
    return JSON.stringify(data);
    На выходе получаю JSON:
    Code:
    [{"LD":"number 0","Status":"logical device : Optimal"},{"LD":"number 1","Status":"logical device : Optimal"},{"LD":"number 2","Status":"logical device : Optimal"}]
    2) Создаю Правило обнаружения:
    Имя: LD list
    Тип: Зависимый элемент данных
    Ключ: ld.list
    Основной ЭД: Discovered LD
    LLD макросы: {#LD} и JSONPath $..LD​

    3) Создаю Прототип элементов данных:
    Имя: LD {#LD} Status
    Тип: Зависимый элемент данных
    Ключ: ld.status.[{#LD}]
    Тип информации: Текст
    Основной ЭД: Discovered LD
    Предобработка: JSONPath $..Status

    Прототипы элементов данных на узле создаются (LD number 0 Status, LD number 1 Status, LD number 2 Status), но значения у них пустые.
    Как мне передать каждому элементу данных (LD number 0 Status, и т.д.) его значение из JSON, который получает элемент данных "Discovered LD​"? Я же указал, что "LD {#LD} Status" - это зависимый элемент данных от "Discovered LD"
  • Kos
    Senior Member
    Zabbix Certified SpecialistZabbix Certified Professional
    • Aug 2015
    • 3404

    #2
    Всё верно, кроме выражения предобработки на последнем шаге. Выражение JSONPath должно быть чем-то вроде:
    Code:
    $[?(@.LD == '{#LD}')]​.Status.first()​
    Смотрите примеры тут (ссылка).

    Comment

    • Tonik
      Junior Member
      • Jun 2023
      • 13

      #3
      Спасибо за пример. Мне подошел следующий вариант:
      Code:
      $..[?(@.LD=='{#LD}')].Status
      Но возникла проблема с преобразованием.
      Значение макроса {#LD} приходит из JSON как ["number 0"] и т.д.(["number 1"], ["number 2"]).
      Поэтому напрямую подставить в выражение $..[?(@.LD=='{#LD}')].Status я его не могу. Так как $..[?(@.LD=='["number 0"]')].Status ничего не находит.
      Поэтому надо ["number 0"] преобразовать в number 0.
      Но если я через JS преобразую его:
      Code:
      const ld = {#LD};
      const value = ld[0];
      return value;
      А потом (на следующем шаге в предобработке) вставляю в $..[?(@.LD=='value')].Status, то выходит ошибка:
      "cannot extract value from json by path "$..[?(@.LD=="value")].Failed": cannot parse as a valid JSON object: invalid object format, expected opening character '{' or '[' at: 'number 0'"
      Я попробовал преобразовать через регулярное выражение в макросах:
      Code:
      $..[?(@.LD=='{{#LD}.regsub("(number.[0-9]*)", \1)}')].Status
      Но так тоже походу нельзя в ​JSONPath.
      Можете подсказать как мне это преобразовать?​

      Comment

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

        #4
        Во-первых, предобработка обрабатывает только текущее полученное значение, с её помощью нельзя преобразовать макрос (по крайней мере, таким образом, как Вы пытаетесь это делать).

        Во-вторых, она в данном месте вообще не нужна; тут дело в другом.
        Originally posted by Tonik
        Спасибо за пример. Мне подошел следующий вариант:
        Code:
        $..[?(@.LD=='{#LD}')].Status
        Но возникла проблема с преобразованием.
        Значение макроса {#LD} приходит из JSON как ["number 0"] и т.д.(["number 1"], ["number 2"]).
        Вероятнее всего, это не совсем так.
        Элементы данных из прототипов, где используется данный LLD-макрос, создаются корректно?
        Посмотрите на имена и ключи сгенерированных элементов данных - в них присутствуют ненужные вам кавычки и квадратные скобки? Если нет, то "значение макроса {#LD} приходит" совершенно таким, как надо.

        Скорее всего, не так отрабатывает уже Ваше выражение JSONPath. Сравните с моим выражением (там функция first() неспроста), а также обратите внимание на поле "Тип" в последней таблице с примерами по ссылке, которую я приводил.

        Comment

        • Tonik
          Junior Member
          • Jun 2023
          • 13

          #5
          Вот как раз имена и ключи сгенерированных элементов данных создаются в виде ["number 0"]. Получается тип "неопределенный". В LLD макросах у правило обнаружения указано $..LD.
          В именах прототипов элементов если я указываю LD {#LD} Status, то имя будет LD ["number 0"] Status.
          В ключе указываю ld.status.[{#LD}], ключ у элемента получается ld.status.["["number 0"]"],
          А если имя преобразую через регулярное выражение LD {{#LD}.regsub("(number.[0-9]*)", \1)} Status, то имя будет LD number 0 Status.
          Функция first() в предобработке прототипа элемента убирает эти квадратные скобки. Например, если бы значение макроса {#LD} было number 0, а не ["number 0"]:
          $..[?(@.LD=='{#LD}')].Status вернет значение ["logical device : Optimal"]
          $..[?(@.LD=='{#LD}')].Status.first()
          вернет значение logical device : Optimal
          Как мне из правила обнаружения получить "определенный" тип, то есть, чтоб в прототипы элементов приходил значения без квадратных скобок и кавычек?​

          Comment

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

            #6
            Originally posted by Tonik
            Вот как раз имена и ключи сгенерированных элементов данных создаются в виде ["number 0"]. Получается тип "неопределенный". В LLD макросах у правило обнаружения указано $..LD.
            В именах прототипов элементов если я указываю LD {#LD} Status, то имя будет LD ["number 0"] Status.
            Что-то не так отрабатывает в этом месте.
            Попробуйте указывать в правиле обнаружения JSONPath для макроса не с двумя точками, а с одной, или же через квадратные скобки:
            Code:
            $.LD
            $['LD']
            Макрос {#LD}​ во время процедуры LLD должен раскрываться в простой текст (без кавычек и квадратных скобок) без лишних плясок с бубном.

            Comment

            • Tonik
              Junior Member
              • Jun 2023
              • 13

              #7
              Я нашел свою ошибку!
              Дело в том, что я проверяю JSONPath на сайте https://jsonpath.com/. А обработка JSON оказывается у него отличная от Zabbix.

              Например:
              JSON - [{ "device": "1", "status": "normal" },{"device": "2", "status": "normal"},{"device": "3", "status": "normal"}]
              JSONPath - $.device
              https://jsonpath.com/ вернет значение: "No match"
              Zabbix вернет значение: 1, 2, 3

              А если JSONPath - $..device
              https://jsonpath.com/ вернет значение:["1"], ["2"], ["3"]
              Zabbix вернет значение: ["1"], ["2"], ["3"]

              Огромное вам спасибо за советы!​

              Comment

              Working...