Ad Widget

Collapse

Расширяем snmp lld скриптами

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Jimson
    Senior Member
    • Jan 2008
    • 1327

    #1

    Расширяем snmp lld скриптами

    Кто уже пытался использовать LLD заметил что во первых, прохода по одному OID не достаточно для вменяемого дискаверинга, во вторых по куцым результатам этого дискаверинга невозможно сделать нормальную фильтрацию.

    Для примера, дискаверинг по интерфейсам дает нам индекс и Descr, а хочется еще
    1) тип интерфейса
    2) админ статус
    3) полный дескрипшен прописанный в конфигурации
    4) RD или VRF name, если интерфейс является forwarding
    5) и тд и тп
    А ведь хочется еще фильтр на это все. Итог: нам нужен JSON в котором кроме всего перечисленного выше еще должен быть {#TAGS} значение которого объединяет важные параметры, по которым мы будем фильтровать, ну например "GigabitEthernet0/2.230 subif adminDown 3850:230 VPN230"

    Сделать все это можно, и достаточно просто, надо использовать в качестве правила дискаверинга "внешнюю проверку", а не встроенный LLD SNMP.

    Уверен каждый сможет это реализовать сам, но все же приведу небольшой пример скрипта для генерации дискаверинга по cisco IP SLA. Загвоздка в том что у ip sla нет ни имени, ни дескрипшена, один только номер и этот номер является индексом. Можно было бы использовать для дискаверинга OID с TargetIPAddress, но он типа OCTET STRING, вообщем это 4 хекс числа, вот облом, можно, конечно, удовлетворится просто номером, но мы все же попробуем собственный дискаверинг и отобразим на графиках {#SNMPVALUE} которое будет содержать читабельный IP адрес тестируемого SLA респондера.

    Code:
    #!/usr/bin/perl -w
    
    use SNMP;
    
    die "Usage: $0 <host> <port> <community>" if ($#ARGV != 2);
    
    $sess = new SNMP::Session(DestHost => "$ARGV[0]:$ARGV[1]",
                    Community => "$ARGV[2]",
                    UseNumeric => 1,
                    NonIncreasing => 1,
                    UseLongNames => 1);
    
    die $sess->{ErrorStr} if ($sess->{ErrorNum});
    
    ($targets) = $sess->bulkwalk(0, 100, [['.1.3.6.1.4.1.9.9.42.1.2.2.1.2']]);
    
    die $sess->{ErrorStr} if ($sess->{ErrorNum});
    
    for $i (0..$#$targets) {
            if ($$targets[$i]->type eq "OCTETSTR" and length($$targets[$i]->val) == 4) {
                    push(@json,
                            {
                                    SNMPINDEX => $$targets[$i]->iid,
                                    SNMPVALUE => join('.', unpack('C*', $$targets[$i]->val))
                            }
                    );
            }
    }
    
    #
    # Output in JSON format
    #
    print "{\n\t\"data\":[";
    $first_data = 1;
    foreach $data (@json) {
            $first_data ? $first_data = 0 : print ",";
            print "\n\t\t{";
            $first_macro = 1;
            while (($macro, $value) = each %$data) {
                    $first_macro ? $first_macro = 0 : print ",";
                    print "\n\t\t\t\"{#", $macro, "}\":\"", $value, "\"";
            }
            print "\n\t\t}";
    }
    print "\n\t]\n}\n";
    Собственно что бы приспособить скрипт под другие нужны надо лишь вставить свои OID, и их может быть несколько:
    Code:
    ($one,$two,$three) = $sess->bulkwalk(0, 100, [['.1.1.1'],['.2.2.2'],['.3.3.3']]);
    Каждый OID сканируется независимо, в результирующих массивах может быть и разныо число элементов. Второй параметр bulkwalk это константа ограничивающая сканирование, защита для дурака, для сканирования индексов интерфейсов на роутере мне, к примеру, прийдется увеличить эту константу до 300+.

    Сама логика укладывается в циклы просматривающие массивы и генерящие на выходе массив хешей @json. Последний кусочек скрипта выводящий JSON в stdout универсален, какие хеши дадите то он и выдаст в виде JSON.

    Update. Прилепил последнюю версию скрипта для дискаверинга интерфейсов. Пример работы где то на третьей странице треда. Параметры Retry и Timeout при инициализации сессии можно изменить по своему усмотрению. Скрипт работает только по SNMPv2, так как для опроса используется GetBulk() и потому что некоторые железки, в часности cisco, не отдают по SNMPv1 таблицу ifXTable.

    До кучи, пример шаблона с данными и графиками и картинга глобальных регулярных выражений, которые в этом шаблоне используются. В шаблоне так же используется макросы:
    SNMP_COMMUNITY который вы можете определить глобально, на темплейте или на хостах, ну собственно последний вариант полезнее всего
    SNMP_PORT скрипту надо передавать, а использовать порт заданный на интерфейсе в конфигурации хоста я не нашел как, то что заявлено в документации у меня не заработало

    SNMP_LLD это строчка, которую будет искать скрипт в дескрипшене (ifAlias) интерфейса и если он ее находит, то в {#TAGS} попадает маркер ",FLAGS,", таким образом вы можем управлять дискаверингом и все подряд интерфейсы не выгребать, использовать это или нет зависит от задачи. Для свичей, например, смысла это особо не имеет, там полезнее сделать регекспы только на признак Physical, т.е. мониторить все физические порты и игнорировать всякие vlanX, а вот для роутеров помечать интерфейсы, которые нужно мониторить, через дискрипшен очень удобно. Я использую {$SNMP_LLD} = "[D]" объявленный глобально.

    Update 2. Актуальная версия скрипта, шаблона и regexp в посте 46
    Update 3. Решение проблемы валидации JSON в Zabbix 2.2+ тут
    Attached Files
    Last edited by Jimson; 05-03-2015, 10:19.
  • zalex_ua
    Senior Member
    Zabbix Certified Trainer
    Zabbix Certified SpecialistZabbix Certified Professional
    • Oct 2009
    • 1286

    #2
    Интересный подход, спасибо.
    Прилинковалл ссылку на топик тут https://support.zabbix.com/browse/ZBXNEXT-581

    Comment

    • Jimson
      Senior Member
      • Jan 2008
      • 1327

      #3
      Я видел этот репорт и как раз он меня заставил задуматься на тему, что невозможно реализовать все хотелки применительно к дискаверинг правилу. Пример по интерфейсам я привел реальный, это то правило что мне нужно для мониторинга PE маршрутизаторов в MPLS сети, завтра сяду писать скрипт.
      Скрипт для SLA был тестом, который я сегодня сделал и все проверил, в том числе много макросов, а не только index+value. Этим же способом можно вытаскавать статичные данные, например, дескрипшены, которые можно использовать в названиях тригеров.

      Кстати, напоролся на непрятное задваивание графиков, оттестить возможности нет пока, но суть заключается в том что если у нас, предположим есть SNMPINDEX и SNMPVALUE и название графика включает в себя оба этих макроса, то при изменении SNMPVALUE создается новый комплект графиков. А может просто глюк.

      P.S. а еще опять разочаровали макросы, какого бубена {HOST.PORT} не доступен везде где доступен {HOST.CONN} я отказываюсь понимать

      Comment

      • zalex_ua
        Senior Member
        Zabbix Certified Trainer
        Zabbix Certified SpecialistZabbix Certified Professional
        • Oct 2009
        • 1286

        #4
        Originally posted by Jimson
        Кстати, напоролся на непрятное задваивание графиков, оттестить возможности нет пока, но суть заключается в том что если у нас, предположим есть SNMPINDEX и SNMPVALUE и название графика включает в себя оба этих макроса, то при изменении SNMPVALUE создается новый комплект графиков. А может просто глюк.
        Не очень похоже но все же проверь вот это https://support.zabbix.com/browse/ZBX-5347
        Версии/ревизии фронтенда и сервера ?

        Мы годик тому назад с тобой обсуждали что в отличии от айтемов (где критерием уникальности есть ключ) у триггеров и графиков критерием уникальности есть имена.
        И если значение какого либо ЛЛД макроса меняется то обьект (триггер, график) будет создан заново (с удалением предыдущих).
        Я не исследовал как в данный момент оно работает, но думаю также.

        Comment

        • Jimson
          Senior Member
          • Jan 2008
          • 1327

          #5
          Originally posted by zalex_ua
          Мы годик тому назад с тобой обсуждали что в отличии от айтемов (где критерием уникальности есть ключ) у триггеров и графиков критерием уникальности есть имена.
          И если значение какого либо ЛЛД макроса меняется то обьект (триггер, график) будет создан заново (с удалением предыдущих).
          Я не исследовал как в данный момент оно работает, но думаю также.
          Уже не помню. Если это так, то это очень плохо, так как сразу отсекает вариант вывода в название графика, скажем, дескрипшена. Ведь при пересоздании комплексные экраны не обновятся. Нужно вводить "ключи" в графики и тригеры, иначе с lld будут проблемы.

          А у меня так вышло что второй комплект графиков создался, а предыдущий не удалился, более того, они остались как lld графики, их и в ручную не удалить. Пришлось в шаблоне клонировать график, в результате на хостах создался третий комплект графиков, после чего я удалил в шаблоне старый график и на хостах удалились первые два, остался только комплект который создался после клонирования. Стремно вообщем как то.

          Comment

          • sproot
            Member
            • Mar 2012
            • 52

            #6
            Jimson, после того как получен TAGS как будет проходить дальнейшая его обработка? Точнее, хотелось бы узнать как получить отдельные подстроки которые входят в TAGS и сформировать на их основе элементы данных/графики. Средствами забикса получиться, не прибегая к внешним скриптам и забикс api? У меня сейчас стоит задача получения всех возможных параметров порта/интерфейса рутера/свича и визуализация их в виде графиков/комплексных экранов. Я пока в раздумьях как лучше всего это оформить...Каждый отдельно взятый порт/интерфейс лучше всего сделать комплексным экраном?

            Comment

            • Jimson
              Senior Member
              • Jan 2008
              • 1327

              #7
              Originally posted by sproot
              Jimson, после того как получен TAGS как будет проходить дальнейшая его обработка? Точнее, хотелось бы узнать как получить отдельные подстроки которые входят в TAGS и сформировать на их основе элементы данных/графики. Средствами забикса получиться, не прибегая к внешним скриптам и забикс api? У меня сейчас стоит задача получения всех возможных параметров порта/интерфейса рутера/свича и визуализация их в виде графиков/комплексных экранов. Я пока в раздумьях как лучше всего это оформить...Каждый отдельно взятый порт/интерфейс лучше всего сделать комплексным экраном?
              TAGS я задумал как макрос по которому можно фильтровать, ведь условие фильтрации в дискавери-правиле работает только по одному макросу, а мне нужно, предположим все ethernet порты, не зашатдауненые, только сабинтерфейсы и только относящиеся к определенным VRF.
              Что же касается самих данных, то они будут присутсвовать в JSON как отдельные макросы, макросов может быть не только два, а сколько угодно. Для примера JSON может выглядеть так:

              {
              "{#SNMPINDEX}":"134",
              "{#SNMPNAME}":"GigabitEthernet0/2.405",
              "{#SNMPALIAS}":"Gi0/2.405",
              "{#SNMPDESCR}":"The best interface",
              "{#SNMPADMIN}":"admup",
              "{#SNMPSTATUS}":"notconnect",
              "{#SNMPRD}":"30850:286",
              "{#SNMPVRF}":"VPN286",
              "{#SNMPTAGS}":"Gi0/2.405 admup notconnect VPN286"
              }

              Соответсвенно правило фильтрации, например,
              {#SNMPTAGS} 'Gi0/(2|3).*adminup.*VPN(280|281|286|304|305)'
              а лучше делать глобальные регекспы, там все красивее можно описать.

              Скрипт такой используется множество раз, например одно дискаверинг правило "ловит" только эзернет порты, другое только АТМ, ибо набор прототипов у этих портов будет разный. А можно вообще расдергать интерфейсы одного маршрутизатора по разным хостам забикса по признаку VRF, это даст возможность псевдо-хост вынести в группу относящуюся к определенному VRF и как следствие дать возможность клиенту видеть загрузку портов на PE маршрутизаторах, но только своих.

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

              Правило дискаверинга выполняется достаточно редко, ну раз в полчаса, у меня так вообще множество дискаверингов который раз в 3-6 часов выполняются и то для проформы. Именно поэтому можно не боясь накладных расходов городить скрипт какой влезет. А вот данные скриптами я бы собирать не стал, никакого сервера не хватит если он будет форкать несколько сотен скриптов в секунду.

              Comment

              • sproot
                Member
                • Mar 2012
                • 52

                #8
                У меня сейчас вот такой зоопарк из железок:
                zabbix=# select name from groups;
                ....
                Juniper ERX
                Cisco Catalyst 3750
                Cisco 10720
                Cisco 2509
                Cisco 2522
                Cisco 2610
                Cisco 2610XM
                Cisco 2611
                Cisco 2620
                Cisco 2620XM
                Cisco 3640
                Cisco 3660
                Cisco 3662
                Cisco 3745
                Cisco 4000
                Cisco 7206VXR
                Cisco 7301
                Cisco 7606
                Cisco 7609
                Cisco ASR1006
                Juniper M7i
                Cisco 4924
                Cisco ME3400
                Cisco ME3600
                Cisco ME6524
                Cisco Catalyst 2924
                Cisco Catalyst 2950
                Cisco Catalyst 3550
                Cisco Catalyst 6509

                + еще не заведена пара десятков единиц другого оборудования. Судя по твоим сообщениям, ты работаешь в провайдинге? Можешь сказать, если у тебя есть такие же железки, то что ты на них мониторишь? И как...:-)

                Comment

                • Jimson
                  Senior Member
                  • Jan 2008
                  • 1327

                  #9
                  Да в провайдинге, но немного в другом спектре - спутниковые каналы передачи данных и VPN. Соответсвенно основная масса данных для мониторинга это данные получаемые с компонентов спутниковых хабов (центральная земная станция блаблабла) и с самих спутниковых терминалов (клиенская сторона) и это у меня 99% данных забикса в настоящее время. Традиционная сеть у нас это 6 7200VXR образующие MPLS сетку, ну и кучка свичей, но это уже не так интересно. Пока с роутеров и свичей я собираю только общие параметры (аптайм, cpu, память, и тп фигня) и данные IP SLA по магистральных каналам. Надо собирать данные по интерфейсам, но тут как раз загвоздка: портянка на 200+ интерфейсов на роутере смысла никакого не имеет, надо как то фильтровать и раскидывать мониторинг интерфейсов по псевдо-узлам, о чем я и писал в предыдущем посте.

                  Comment

                  • OKyHb
                    Senior Member
                    • Sep 2010
                    • 103

                    #10
                    есть SNMPINDEX и SNMPVALUE и название графика включает в себя оба этих макроса, то при изменении SNMPVALUE создается новый комплект графиков
                    Перешли с 2.0.2 на 2.0.3, используем SNMP LLD по ifAlias (никаких скриптов, всё стандартное). И тоже, если название прототипа графика включает в себя SNMPINDEX и SNMPVALUE, при изменении ifAlias получаем новый график. И при этом старый график у хоста удалить вручную нельзя, так как он из темплейта.

                    На support.zabbix.com такую проблему не нашёл. Неужели проявляется только у нас?

                    Comment

                    • Jimson
                      Senior Member
                      • Jan 2008
                      • 1327

                      #11
                      Индекс по ifAlias это очень сильно, учитывая что index запросто может слететь на большинстве оборудовании (при переконфигурации или при смене софта), а ifAlias по определению не является фиксированным именем интерфейса.

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

                      Самый простой вариант пропатчить "под себя" это добавить дополнительное имя в таблицу graphs, реализовать его вывод при прорисовке графика и ввод его значения при редактировании, ну и экспорт-импорт поправить если надо. Трогать существующее имя графика нельзя, и изменить его поведение тоже нельзя, так как на этом атрибуте завязана логика добавления/удаления LLD графиков, по сути имя графика используется как "ключ".

                      Comment

                      • OKyHb
                        Senior Member
                        • Sep 2010
                        • 103

                        #12
                        Индекс по ifAlias это очень сильно
                        Так уж сложилось. Просто в наличии приблизительно 6к абонентских свичей с ~180к портов. А снимать надо не только Octets, но и BroadcastPkts/MulticastPkts/...
                        И если мониторить не абсолютно все порты, а только те, где абонент (на порту есть alias) - нагрузка заметно снижается.

                        Comment

                        • Jimson
                          Senior Member
                          • Jan 2008
                          • 1327

                          #13
                          Ну я уже писал как я решил эту проблему, и собственно тред этому и посвящен. Прилепил еще раз скрипт через который дискаверить интерфейсы, фильтр при этом делается на {#IFTAGS}, например,

                          фильтр ",AdminStatus:up," даст только интерфейсы которые административно включены
                          фильтр ",FLAG," даст только те интерфейс у которых в дескрипшене есть шаблон (метка), которую мы указываем при выхове скрипта - как раз то что вам нужно
                          можно так же фильтровать по типу интерфейса, а так же есть флаг по которому можно отфильтровать "физические" интерфейсы и интерфейсы для которых доступны 64 бит счетчики

                          при этом, использование такого скрипта дает возможность пользовать имя интерфейса {#IFDESCR} и в тоже время алиас, если очень уж нужно - {#IFALIAS}

                          ну и шаблон до кучи приложил
                          Attached Files

                          Comment

                          • OKyHb
                            Senior Member
                            • Sep 2010
                            • 103

                            #14
                            Действительно, со скриптом получилось красивее и удобнее. Реально спасибо.

                            Надо была с ним и переходить на LLD, так как теперь в процессе изменения темплейта всплыла проблема - из-за большого к-ва хостов, на которые привязан темплейт, довольно проблематично удалить неправильные прототипы графиков. Пробую удалить один график - 10 минут один cpu в полке, но ничерта не удаляется.

                            Есть мысль попробовать напрямую через mysql поудалять записи из таблицы graphs, но боюсь нарушить какие-то взаимосвязи. Может у кого-то есть решения и для таких проблем? )

                            Comment

                            • Jimson
                              Senior Member
                              • Jan 2008
                              • 1327

                              #15
                              Для графиков которые созданы при дискаверинге есть еще одна таблица, там указывается ид и название графика (оно используется как ключ) и идентификатор прототипа. Прежде чем что то удалять из таблицы graphs надо разобраться со связями LLD, возможно вам удастся удалить все графики кучей используя в качестве ключа id прототипа.

                              Comment

                              Working...