Ad Widget

Collapse

Как суммировать элементы, которых может не быть?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • balduser
    Junior Member
    • Oct 2022
    • 16

    #1

    Как суммировать элементы, которых может не быть?

    Похожие вопросы в истории поиска я уже находил, но ответ по ним - нет. Может, взгляд под другим углом поможет экспертам подсказать мне решение проблемы?
    У меня zabbix 5.0 (обновиться не получится). Рассмотрю абстрактный случай: Есть хост, для которого я создал 2 зависимых элемента: newping[1] и newping[2]. Оба являются dependent от ICMP ping response time. Мне нужно высчитать сумму значений этих элементов, для этого конечно же я делаю last(newping[1])+last(newping[2]). Но что, если заранее неизвестно, сколько параметров newping должно суммироваться на хосте? То есть, их может быть 1, а может быть 6... Сделать sum(newping[*],#1) zabbix, конечно же, не даёт. Можно было бы сделать last(newping[1])+...+last(newping[6]), но если в этой цепочке будет несуществующий элемент, сумма вообще не будет вычисляться... Очень не хватает функции, которая при отсутствии указанного ключа просто возвращала бы 0... Читал, что sum в некоторых версиях возвращает 0, но в моей - нет.

    Хотел решить проблему другим образом: сделал правило обнаружения, которое в зависимости от заданного мной на уровне шаблона макроса, javascript'ом генерирует формулу в LLD-макрос {#FORMULA}, которую я подставляю в прототип calculated item как есть: {#FORMULA} в поле formula. Но правило не может создать элемент из прототипа, пишет: Cannot create item, error in formula: not numeric value in macro "{#FORMULA}".

    Теперь конкретика, зачем это нужно. Есть железка, которая мониторится. Внутри неё есть 6 сервис-бандлов, по каждому из которых собирается почти 300 метрик. Потом они суммируются, и получается несколько итоговых величин. Пока неизвестно, будут ли задействованы все сервис-бандлы, поэтому хочется создать шаблон, в котором количество метрик можно масштабировать одной переменной. И если с масштабированием метрик нижнего уровня правило обнаружения и прототипы отлично справляются при помощи javascript, то с итоговым суммированием метрик, которые отсутствуют, zabbix справиться не даёт...
  • Kos
    Senior Member
    Zabbix Certified SpecialistZabbix Certified Professional
    • Aug 2015
    • 3404

    #2
    Originally posted by balduser
    Сделать sum(newping[*],#1) zabbix, конечно же, не даёт.
    А вот это, как раз, повод задуматься над обновлением - начиная с версии 6.0 подобные вещи можно делать штатно при помощи агрегируемых функций и и вложенных в них функций foreach.
    По первой ссылке второй пример как раз для вашего случая.

    Comment

    • balduser
      Junior Member
      • Oct 2022
      • 16

      #3
      Для себя нашёл решение, хотя оно и не сильно масштабируемое: создавать моковые элементы данных (пустышки). Например, когда нужно подсчитать суммарный трафик по 8 очередям QOS, но мы заранее не можем знать, какие очереди будут задействованы на том или ином порту. В таком случае опрос SNMP по OID'у с номером очереди, которой нет, даже не вернёт 0, а вернёт ошибку: No Such Instance currently exists at this OID. Поэтому нам нужно сделать так, чтобы были элементы с ключом соответствующего вида, которые возвращали бы 0.
      Задействованные очереди QOS дискаверятся в одном правиле, а незадействованные должны быть созданы в другом. Конечно же, для этого нужно написать скрипт на js в препроцессинге, чтобы правильно их определить и создать. Потом, уже зная, что у нас всегда 8 элементов данных с ключами типа item.name[{#SNMPINDEX}.1], item.name[{#SNMPINDEX}.2] и так далее, их остаётся только просуммировать в calculated элементе.
      Чтобы сделать элемент, который всегда возвращает 0, я в шаблоне создал один элемент (не прототип) типа Simple check с ключом icmpping[0], а в препроцессинге (js) на всякий случай указал "return 0;". Моковые элементы просто создаются зависимыми от этого элемента и всегда возвращают 0.
      Поначалу стояла проблема, как в двух правилах одного шаблона создать элементы, которые имели бы ключи одного вида, например qos.disc.pkts[{#SNMPINDEX}.{#QUEUE}], ведь заббикс не разрешает так делать. Решение нашлось в том, что в одном из правил названия макроса в препроцессинге было изменено, например на {#INDEX_SHMINDEX}.​

      Comment

      • Alex_UUU
        Senior Member
        • Dec 2018
        • 541

        #4
        Еще вариант (от программера:-) ты создаешь элементы прототипами, но у них как минимум ключ уникальный newping[{#ID}]. Сделай ЭД - внешняя проверка где по апи вытаскиваешь все элементы по маске ключа и суммируешь.

        ЗЫ. В заббиксе нет возможности в формуле, триггере, работать с ЭД, созданные прототипами с разных хостов. ПОэтому мне пришлось аналогичным образом в один хост дублировать ЭД с другого. И уже сравнивать.

        Comment

        • balduser
          Junior Member
          • Oct 2022
          • 16

          #5
          Понял, что в прошлом ответе я нагородил фигни с моковыми элементами. Решил свою задачу проще. Вдруг кому пригодится:
          Если идти от конца к началу, то итоговый элемент (прототип) имеет формулу
          Code:
          last(item.name[{#ITEM_1}])+last(item.name[{#ITEM_2}])+last(item.name[{#ITEM_N}])
          Препроцессинг правила discovery в каждом словаре даёт те самые ключи '{#ITEM_1}', '{#ITEM_2}', '{#ITEM_N}', которым соответствуют либо индексы реально существующих элементов, либо '0'. То есть формула разворачивается например в
          Code:
          last(item.name[123.456.1])+last(item.name[456.79.5])+last(item.name[0])
          Дальше остаётся только обеспечить, чтобы существовал элемент с ключом item.name[0]. Для этого, как я писал выше, сначала я создаю простую проверку с ключом icmpping[0], а потом создаю зависимый от него элемент с ключом item.name[0].

          Comment

          • Alex_UUU
            Senior Member
            • Dec 2018
            • 541

            #6
            А что делать, если вдруг рабочих элементов будет N+1?

            Comment

            • balduser
              Junior Member
              • Oct 2022
              • 16

              #7
              Правильно прогнозировать количество рабочих элементов, делать запас. Или поставить zabbix 6, там, говорят, о нас позаботились. Ну или выносить суммирование ключей во внешний скрипт...

              Comment

              Working...