Ad Widget

Collapse

Проблема мониторинга уровня сигнала SFP на отключенных портах

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • madbel
    Junior Member
    • Nov 2025
    • 1

    #1

    Проблема мониторинга уровня сигнала SFP на отключенных портах

    Всем привет.

    У меня есть устройства cisco и я собираю данные при помощи заббикс. Для автоматизации мне нужны LLD. Я хочу опросить устройство об его уровнях сигнала только на включенных портах. Но проблема в том, что oid разные! Вот что я смог найти: oid для статуса порта 1.3.6.1.2.1.2.2.1.7[тут может быть например от 10001 до 10024] (up или down)
    оид для имени интерфейса 1.3.6.1.2.1.31.1.1.1.1[тут может быть например от 10001 до 10024, 10101, 10102] (FastEthernet/GigabitEthernet)

    oid для сигнала 1.3.6.1.4.1.9.9.91.1.1.1.1.4[тут может быть например от 1026 до 1040] (тут будут значения сигнала, по типу -400, -237, их предобработкой я умножаю на 0.1)
    oid, который содержит номер порта 2.47.1.1.1.1.14[тут может быть например от 1026 до 1040] со значением от "10001" до "10024" и "10101", "10102".

    Как мне все это связать, чтобы триггер правильно составить? Есть идеи?
    Потому что сейчас я получаю уровень сигнала для портов, которые в состоянии shutdown и значения -35, -40 срабатывают на триггере, при этом делать костыль, исключая эти уровни сигнала в триггере не считаю хорошей идеей. Не могу понять, как мне связать разные oid и сделать их зависимыми. Чтобы уровень сигнала собирался только для портов, которые в апе. Нашел лишь одну статейку на форуме на этот счет, но там решение было для zabbix 5.4, я использую zabbix 7.0.17
  • Andrejs Poddubņaks
    Junior Member
    • Nov 2025
    • 18

    #2
    Привет!
    Исходя из твоего описания проблемы, можно попробовать сделать следующее:
    1. Сделать SNMP walk-item
    Тип SNMP agent, key вида, например: walk_sfp c OID`ами:
    1.3.6.1.4.1.9.9.91.1.1.1.1.4 - уровень сигнала
    1.3.6.1.2.1.47.1.1.1.1.14 - соответствующий ifIndex (10001, 10101 и тд)
    В официальной документации SNMP OID через walk[ ]. Ссылка на тех.статью: https://www.zabbix.com/documentation...snmp_oids_walk

    2. На этом item’e сделать dependent discovery-rule.
    В препроцессинге discovery шаг SNMP walk to JSON, дальше при необходимости JS, чтобы собрать JSON с макросами вида:
    {#SENSORINDEX} - индекс в таблице DOM (1026...)
    {#IFINDEX} - ifindex (10001, 10101...)

    3. В Item-prototype:
    - Уровень сигнала:
    1.3.6.1.4.1.9.9.91.1.1.1.1.4.{#SENSORINDEX}
    -Статус порта:
    1.3.6.1.2.1.2.2.1.8.{#IFINDEX} (ifOperStatus=up/down)

    Из технической документации: 5 Discovery of SNMP OIDs (legacy)

    4. В триггер-прототипе по уровню сигнала добавить условие, что порт должен быть up, например:
    {TEMPLATE:sfp.signal.last()} < -18
    and
    {TEMPLATE:ifOperStatus.last()} = 1


    Надеюсь правилбно понял проблему и направил в сторону решения проблемы! ​

    Comment


    • madbel
      madbel commented
      Editing a comment
      Оно не вяжется. Уровень сигнала будет иметь 1.4.1026, а статус порта 2.1.8.10101, при таком подходе я не смогу объяснить триггеру, что 1026 нужно "связать" с 10101. Да и при этом надо сделать это динамически, чтобы я в каждом устройстве эту привязку не делал.
      У меня в голове примерно такой алгоритм:
      1) получить оид статуса порта [10101] со значением (up/down)
      2) получить оид сигнала [1026] со значением (-40)
      3) получить оид номера порта 2.47.1.1.1.1.14.[1026] со значением (10101)

      Как-то объяснить, что оид сигнала 1026 надо связать с оид номера порта, а значение номера порта подставить в оид статуса порта, но это звучит как-то очень нагромождено, и не факт, что работоспособно, вот и думаю, может есть еще идеи у кого?
  • Kos
    Senior Member
    Zabbix Certified SpecialistZabbix Certified Professional
    • Aug 2015
    • 3404

    #3
    Я бы пробовал объединять нужные данные с помощью JavaScript-препроцессинга в правиле обнаружения.
    Идея такая: наверняка у вас уже есть правило LLD, которое использует для обраружения стандартные таблицы, где есть IfAdminStatus, IfAlias и т.п. поля. Для того, чтобы сделать тем же правилом LLD ещё и прототип элемента данных для уровня сигнала, не хватает индекса в таблице OID=1.3.6.1.4.1.9.9.91.1.1.1.1.4 (поскольку там индексирование другое). Но эти индексы можно извлечь из таблицы с OID=2.47.1.1.1.1.14, где нужные данные есть. Остаётся только их скомбинировать, что (теоретически) можно сделать скриптом.

    Могу на досуге попробовать с этим поиграться, но нужен пример конкретных данных.
    Если не секрет, то попробуйте, пожалуйста, сделать следующее:
    • создать на хосте одного из устройств (не в шаблоне!) тестовый элемент данных с любым ключом и таким значением в поле SNMP OID:
    Code:
    walk[1.3.6.1.2.1.2.2.1.7,1.3.6.1.2.1.31.1.1.1.1,2.47.1.1.1.1.14]
    • нажать кнопку "Test", чтобы получить результат от устройства;
    • скопипастить сюда результат (можно сократить - например, дать данные только по пяти конкретным интерфейсам, но чтобы в последней таблице тоже были данные именно по этим интерфейсам).

    Comment


    • madbel
      madbel commented
      Editing a comment
      Да, вы абсолюнто правы, у меня есть LLD для опроса Admin и Oper статуса. Так и есть, я получаю данные по admin статусу с помощью 1.3.6.1.2.1.2.2.1.7, а сигнал хранится в другой таблице 1.3.6.1.4.1.9.9.91.1.1.1.1.4. И единственное, через что это можно было бы как-то связать (как я это увидел, это 2.47.1.1.1.1.14 (тут немного ошибся, полностью будет 1.3.6.1.2.1.47.1.1.1.1.14, у которого после цифры 14 будет, например, 2020, а значением будет 10101 (который будет уже внутри оида для статуса). Полный вывод не могу привести, потому что Zabbix находится в корпоративном DMZ. Вот пример, о котором вы просили:
      Я выбрал тип данных как "текст"

      .1.3.6.1.2.1.2.2.1.7.10001 = INTEGER: 1
      .1.3.6.1.2.1.2.2.1.7.10024 = INTEGER: 1
      .1.3.6.1.2.1.2.2.1.7.10101 = INTEGER: 1
      .1.3.6.1.2.1.2.2.1.7.10102 = INTEGER: 1

      .1.3.6.1.2.1.31.1.1.1.1.10001 = STRING: "Fa0/1"
      .1.3.6.1.2.1.31.1.1.1.1.10024 = STRING: "Fa0/24"
      .1.3.6.1.2.1.31.1.1.1.1.10101 = STRING: "Gi0/1"
      .1.3.6.1.2.1.31.1.1.1.1.10102 = STRING: "Gi0/2"

      .1.3.6.1.2.1.47.1.1.1.1.14.1010 = STRING: "10001"
      .1.3.6.1.2.1.47.1.1.1.1.14.1033 = STRING: "10024"
      .1.3.6.1.2.1.47.1.1.1.1.14.1036 = STRING: "10101"
      .1.3.6.1.2.1.47.1.1.1.1.14.1042 = STRING: "10102"

      Ну и от себя на всякий случай добавлю уровни сигнала:
      .1.3.6.1.4.1.9.9.91.1.1.1.1.4.1040 = INTEGER: -58 ( отправляемый сингал TX для Gi0/1 )
      .1.3.6.1.4.1.9.9.91.1.1.1.1.4.1041 = INTEGER: -23 ( принимаемый сингал RX для Gi0/1 )
      .1.3.6.1.4.1.9.9.91.1.1.1.1.4.1046 = INTEGER: -61 ( отправляемый сингал TX для Gi0/2 )
      .1.3.6.1.4.1.9.9.91.1.1.1.1.4.1047 = INTEGER: -164 ( отправляемый сингал RX для Gi0/2 )

      Это вообще можно между собой завязать?
      Информацию о том, к какому порту я это отношу я беру из оида .1.3.6.1.2.1.47.1.1.1.1.7, здесь для 1036 = STRING: "GigabitEthernet0/1"
      Last edited by madbel; 19-11-2025, 12:53. Reason: UPD

    • Kos
      Kos commented
      Editing a comment
      Да, спасибо. Попробую поиграться с этим на досуге.
  • Kos
    Senior Member
    Zabbix Certified SpecialistZabbix Certified Professional
    • Aug 2015
    • 3404

    #4
    Да, спасибо. Попробую поиграться с этим на досуге.
    Ну вот у меня получилось примерно так.
    Входные данные:
    • элемент данных с ключом walk[1.3.6.1.2.1.2.2.1.7,1.3.6.1.2.1.31.1.1.1.1,1.3.6.1 .2.1.47.1.1.1.1.14]
    • первый шаг предобработки: "SNMP walk to JSON", со следующими параметрами:
    Field name OID prefix Format
    ifAdmin .1.3.6.1.2.1.2.2.1.7 Unchanged
    ifAlias .1.3.6.1.2.1.31.1.1.1.1 Unchanged
    sfpLink .1.3.6.1.2.1.47.1.1.1.1.14 Unchanged
    • предполагаем, что для каждого интерфейса есть запись в первой таблице (ifAdmin).
    Тогда вторым шагом предобработки делаем "JavaScript" с таким кодом:
    Code:
    //transform source string into JSON object
    var val_json = JSON.parse(value);
    var index = {}, snmpindex;
    
    //first pass - collect mapping for sfpLink ({#SNMPINDEX} -> {#SFPINDEX})
    for (i in val_json) {
        if ('sfpLink' in val_json[i]) {
            index[val_json[i]['sfpLink']] = val_json[i]['{#SNMPINDEX}'];
            delete val_json[i]['sfpLink'];
        }//if
    }//for
    
    //second pass - add the {#SFPINDEX} macro and remove unneeded array members
    for (i=val_json.length-1; i>=0; i--) {
        snmpindex = val_json[i]['{#SNMPINDEX}'];
        if (snmpindex in index) {
            val_json[i]['{#SFPINDEX}'] = index[snmpindex];
        }
        if (! ('ifAdmin' in val_json[i])) {
            val_json.splice(i,1);
        }
    }
    
    return JSON.stringify(val_json);
    Результат - получая на входе данные из вашего примера, имеем на выходе (отсортировано и отформатировано для наглядности):
    Code:
    [
     {"{#SNMPINDEX}":"10001","ifAdmin":"1","ifAlias":"Fa0/1","{#SFPINDEX}":"1010"},
     {"{#SNMPINDEX}":"10024","ifAdmin":"1","ifAlias":"Fa0/24","{#SFPINDEX}":"1033"},
     {"{#SNMPINDEX}":"10101","ifAdmin":"1","ifAlias":"Gi0/1","{#SFPINDEX}":"1036"},
     {"{#SNMPINDEX}":"10102","ifAdmin":"1","ifAlias":"Gi0/2","{#SFPINDEX}":"1042"}
    ]​
    То есть, к уже имеющимся данным добавляем LLD-макрос {#SFPINDEX}, указывающий на индекс в таблице, которая содержит уровень сигнала.
    Дальше уже дело техники - используем нужные макросы по вкусу в прототипах (элементов данных, триггеров, графиков).

    Да, если в вашем правиле обнаружения в первом шаге предобработки вместо "ifAdmin" в поле "Field name" указано что-то другое (например, "ifAdminStatus" или "{#IF.ADMIN.STATUS}"), то соответственно надо скорректировать и строку скрипта во втором цикле:
    Code:
    ...
        if (! ('ifAdmin' in val_json[i])) {
    -----------^^^^^^^^^
    ...
    ​
    Last edited by Kos; 24-11-2025, 10:10.

    Comment


    • madbel
      madbel commented
      Editing a comment
      Спасибо большое за помощь! Как будет время, обязательно протестирую и дам обратную связь, пока что загруженная неделя планируется. Если что с нейронкой посижу

    • Kos
      Kos commented
      Editing a comment
      Получилось ли попробовать?
Working...