Child pages
  • Performance Management в NOC Microservices

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Пройдёмся по этим шагам подробнее:Проверяем


Настрока Managed Object

  • Caps

Настройка Managed Object Profile

Идём в "Service Activation" -> Setup -> "Managed Object Profile". Выбираем существующий или создаём новый профиль. В нём, на вкладке Metrics нажимаем Add и выбираем метрику, которую необходимо собирать. Для этого достаточно заполнить 3 поля:

  • Metric Type - метрика
  • Active - (включит сбор метрики)
  • Is store - сохранять метрику в БД
  • По необходимости, указываем пороги (описаны в разделе ниже)

Image Removed

Image Removed

После, переходим на вкладку "Periodic Discovery" и активируем сбор метрик (устанавливаем галочка Enable и Metric). По необходимости, настраиваем интервал обхода.

Image Removed

Настройка сбора метрик с интерфейсов

Метрики для интерфейсов настраиваются в Inventory -> Setup -> "Interface Profiles". В нём необходимо аналогично Managed Object Profile добавить метрики.

Image Removed

После этого привязать профиль к интерфейсам. Это можно сделать в меню Inventory -> Interfaces. Необходимо в выпадающем списке выбрать MO и назначить профили. В это же меню можно попасть по кнопке Interfaces из "Service Activation" -> "Managed Object" -> <MO>.

Image RemovedImage RemovedImage Removed

Настройка Interfaces Classification Rules

Делается опционально-обязательно. Предназначены для автоматического назначения профила интерфейса на интерфейс. Конечно, можно вручную устанавливать профили интерфейсов, но это не продуктивно(smile) Поэтому можно расписать правила классификации. Делается это  из меню Inventory -> Setup -> "Interface Classification Rule".

Подробно работа с правилами расписана тут: Классификация интерфейсов.

Настройка Dashboard

Просмотр метрик идёт через Dashboard. Он доступен из интерфейса MO: в этом случае, он, автоматически, настраивается на отображение всех метрик, собираемых с данного MO или по адресу https://<AddressNOCWeb>/ui/grafana:

Image RemovedImage Removed

Note

Если интерфейс Графаны открывается первый раз: необходимо настроить источник данных, иначе вместо реальных графиков будет подставляться случайные величины.

Для настройки DataSource необходим админский доступ к Графане (по умолчанию, он у пользователя admin). В левом верхнем углу кликнуть по значку графаны, далее опция "Data Sources". После этого нажать кнопку Add в верхнем меню.

Image RemovedImage Removed

При добавлении указываем следующие опции:

  • Name (может быть любой)
  • Обязательно указываем галочку Default (по умолчанию)
  • Type выбираем установленную версию InfluxDB (или близкую к ней)
  • В URL - адрес InfluxDB (если стоит на отдельном хосте - то необходимо указать адрес этого хоста), порт 8086 - по умолчанию
  • Access - Proxy (не путать с http_proxy!) это режим доступа к данным.
  • Вкладки Аутентификации оставляем не отмеченными
  • InfluxDB Details указываем в соответствии с теми, которые прописывали при развёртывании НОКа (по умолчанию везде noc)

Проверить настройки можно кнопкой "Test Connection". После нажимаем Save. Наслаждаемся эффектом.

Image Removed

...

Создание MetricTypes

В общем-то, это единственное что осталось от россыпи настроек Метрик из предыдущего PM. Обитает в разделе "Performance Management" -> Setup -> "Metric Types".На главной странице доступен фильтр, по первой части имени (до |). И кнопка добавить Add.

Image RemovedImage Removed

При добавлении полей не много. Из интересных - Scope, условно, это область в которой происходит сбор метрик. На данный момент их 2:

  • Object. Метрики собирают параметры самого MO (процессор, температура и пр...)
  • Interfaces. Метрики собираются с интерейсов (при сборе скрипту передаётся ifindex)

Measure - мера, единица измерения. Специально ни на что не влияет. Но отображается на графике.

Добавление SNMP OID

После добавления метрики. Необходимо где-то связать её с конкретным OID'ом. Данная настройка переехала непосредственного в скрипт get_metric. Там присутствует такая конструкция следующего вида (заглянем в Cisco.IOS.get_metrics):

Code Block
languagepy
themeRDark
from noc.sa.profiles.Generic.get_metrics import Script as GetMetricsScript
from noc.core.script.metrics import percent


class Script(GetMetricsScript):
    name = "Cisco.IOS.get_metrics"

    SNMP_OIDS = GetMetricsScript.merge_oids({
        "Subscribers | IPoE": [
            ("SNMP", "1.3.6.1.4.1.6527.3.1.2.33.1.107.1.65.1", "gauge", 1)
        ],
    })

Вот то, что SNMP_OIDS и есть словарик с OID. Он имеет следующий вид:

  • "Subscribers | IPoE" - это Metric Type
  • SNMP - метод сбора (других, пока, нет)
  • дальше идёт OID
  • дальше тип OID'a. Их два: gauge и counter
  • 1 - это множитель (или выражение для вычисления метрики)

Для просты, приведём пару примеров (можно посмотреть скрипты get_metrics для других профилей). Добавим для IOS метрики памяти и процессора ("CPU | Usage" и "Memory | Usage"). Для CPU всё просто: добавляем запятую после "Subscribers | IPoE", и прописываем "CPU | Usage". 

Для "Memory | Usage" всё сложнее. Посмотрев MIB'ы выясняем - Cisco возвращает метрики MemFree и MemUsage, а нам необходимо получить проценты (хотя, можно остановиться на сборе этих 2 метрик, добавив соответствующие типы (Metric Type)). Поэтому нам необходимо сделать расчёт процентов по полученным данным. Для этого, как раз, и нужен параметр, который 1. Вместо него можно подставлять свои формулы.

Code Block
languagepy
from noc.sa.profiles.Generic.get_metrics import Script as GetMetricsScript
from noc.core.script.metrics import percent_one

class Script(GetMetricsScript):
    name = "Cisco.IOS.get_metrics"
    SNMP_OIDS = GetMetricsScript.merge_oids({
        "Subscribers | IPoE": [
            ("SNMP", "1.3.6.1.4.1.6527.3.1.2.33.1.107.1.65.1", "gauge", 1)
        ],
        "CPU | Usage": [
            ("SNMP", "1.3.6.1.4.1.9.9.109.1.1.1.1.7.1", "gauge", 1)
        ],
        "Memory | Usage": [
            (
                "SNMP",
                [
                    "1.3.6.1.4.1.9.9.48.1.1.1.6.1",
                    "1.3.6.1.4.1.9.9.48.1.1.1.5.1"
                ],
                "gauge",
                percent_one
            )
        ]
    })

Для написания своих формул идём в "<noc>/core/script/metrics.py" и добавляем своё (percent_one). На вход подаётся две переменных. Поэтому в параметр после SNMP мы прописываем 2 OID.

Code Block
languagepy
def percent(value, total):
    """
    Convert absolute and total values to percent
    """
    if total:
        return float(value) * 100.0 / float(total)
    else:
        return 100.0

def percent_one(value, total):
    """
    Convert absolute and total values to percent
    """
    if total:
        return float(value) * 100.0 / (float(total) + float(value))
    else:
        return 100.0

def sum(*args):
    """
    Returns sum of all arguments
    """
    return reduce(lambda x, y: x + y, args)

def subtract(*args):
    """
    Subtract from first arguments
    """
    return args[0] - reduce(lambda x, y: x + y, args[1:])

Вот, пока всё делается так.

Разбор сложных случаев планируется в отдельной статье(smile).

Отладка

Мы всё сделали, а данных таки нет. Попробуем выяснить - в каком месте может возникнуть проблема.

Скрипты

Чтобы проверить, нет ли ошибки в скриптах, можно воспользоваться механизмом отладки, только, дополнительно передать в скрипт парметры. Делается это так:

Code Block
languagebash
# ./noc script --debug Cisco.IOS.get_metrics "xxx-sw61" metrics:='{"Memory | Usage": {"scope": "o"}}'
.....
 Result: [{'scale': 1.0, 'name': 'Memory | Usage', 'tags': {'object': None}, 'ts': 1469865495320386816, 'value': 49.583421519590374, 'type': 'gauge'}]
ifindex

Если проблемы возникли со считыванием метрик интерфейсов, а остальные считываются без проблем - то необходимо проверить наличие ifindex. Сделать это можно запустив отладку скрипта get_interfaces (обратите внимание на наличие поля "snmp_ifindex"))

Code Block
languagebash
# ./noc script Cisco.ASA.get_interfaces "XXXX-fw02"
......
[{'interfaces': [{'oper_status': True, 'snmp_ifindex': 2, 'name': 'Et 0/0', 'subinterfaces': [{'snmp_ifindex': 10, 'name': 'Et 0/0.539', 'enabled_afi': ['IPv4'], 'enabled_protocols': [], 'mac': '
InfluxDB

К ней можно подключиться и посмотреть - пишутся ли данные в базу.

Code Block
languagebash
# influx
Visit https://enterprise.influxdata.com to register for updates, InfluxDB server management, and monitoring.
Connected to http://localhost:8086 version 0.9
InfluxDB shell 0.9
> use noc
> show tag values with key = object;
name: objectTagValues
---------------------
object
ASA-XXXX
ASA-XXXX-2
XXXX-Nab
 
> select * from /.*/ limit 1 /"Осторожно, если у вас много метрик!"
> select * from /.*/ limit 1
name: CPU | Usage
-----------------
time                    interface       object          value
1469550770000000000                     xxx-sw71        10

name: Interface | Load | In
---------------------------
time                    interface       object          value
1465478790000000000     Gi 2/0/27       xxx-sw61        0

name: Interface | Load | Out
----------------------------
time                    interface       object          value
1465478790000000000     Gi 2/0/27       xxx-sw61        0

Подробнее форматы запросов можно посмотреть InfluxDB Query language Необходимо проверить ManagedObject:

  • SNMP Community необходим прописанный Communtiy RO (либо указан в назначенный Профиль аутентификации (AuthProfile)) в случае снятия метрик по SNMP.

Image Added

Warning

В случае, если назначен профиль аутентификации (Auth Profile) на устройство, то будет использован он, даже если поле SNMP RO в нём пустое (в этом случае система будет писать, что отсутствует community)

  • На вкладке Capabilities, необходимо убедиться, что проверка SNMP на устройстве завершилась успешно (правый скриншот). Вкладка Capabilities (Возможности) заполняется по итогам работы опроса Caps:

Image AddedImage Added

  • SNMP Capabilities:
    • SNMP - базовая проверка SNMP, проходит путём опроса устройства OID  sysObjectID (.1.3.6.1.2.1.1.2.0)
    • SNMP | Bulk - поддержка устройством пакетных (Bulk) запросов
    • SNMP | IF-MIB - разрешён ли для опроса IF-MIB (если данного капса нет, то опрос метрик интерфейсов проходить не будет)
    • SNMP | IF-MIB | HC - поддержка 64-разрядных счётчиков
    • SNMP | v1, v2c, v3c - поддержка версии SNMP

Настройка Managed Object Profile

Идём в "Service Activation" -> Setup -> "Managed Object Profile". Выбираем существующий или создаём новый профиль. В нём, на вкладке Metrics нажимаем Add и выбираем метрику, которую необходимо собирать. Для этого достаточно заполнить 3 поля:

  • Metric Type - метрика
  • Active - (включит сбор метрики)
  • Is store - сохранять метрику в БД
  • По необходимости, указываем пороги (описаны в разделе ниже)


Image Added

Image Added

После, переходим на вкладку "Periodic Discovery" и активируем сбор метрик (устанавливаем галочка Enable и Metric). По необходимости, настраиваем интервал обхода.

Image Added


Настройка сбора метрик с интерфейсов

Метрики для интерфейсов настраиваются в Inventory -> Setup -> "Interface Profiles". В нём необходимо аналогично Managed Object Profile добавить метрики.

Image Added

После этого привязать профиль к интерфейсам. Это можно сделать в меню Inventory -> Interfaces. Необходимо в выпадающем списке выбрать MO и назначить профили. В это же меню можно попасть по кнопке Interfaces из "Service Activation" -> "Managed Object" -> <MO>.

Image AddedImage AddedImage Added

Настройка Interfaces Classification Rules

Делается опционально-обязательно. Предназначены для автоматического назначения профила интерфейса на интерфейс. Конечно, можно вручную устанавливать профили интерфейсов, но это не продуктивно(smile) Поэтому можно расписать правила классификации. Делается это  из меню Inventory -> Setup -> "Interface Classification Rule".

Подробно работа с правилами расписана тут: Классификация интерфейсов.

Настройка Dashboard

Просмотр метрик идёт через Dashboard. Он доступен из интерфейса MO: в этом случае, он, автоматически, настраивается на отображение всех метрик, собираемых с данного MO или по адресу https://<AddressNOCWeb>/ui/grafana:

Image AddedImage Added

Note

Если в интерфейсе Графаны вместо в значениях метрик выводится случайная величина: необходимо проверить настройки источника данных (DataSource) в графане.

Для настройки Источника данных (DataSource) необходим админский доступ к Графане (по умолчанию, он у пользователя admin). В левом верхнем углу кликнуть по значку графаны, далее опция "Data Sources". После этого нажать кнопку Add в верхнем меню.

Image AddedImage Added

При добавлении указываем следующие опции:

  • Name (может быть любой)
  • Обязательно указываем галочку Default (по умолчанию)
  • Type выбираем ClickHouse (или близкую к ней)
  • В URL - адрес ClickHouse (если стоит на отдельном хосте - то необходимо указать адрес этого хоста), порт 8086 - по умолчанию
  • Access - Proxy (не путать с http_proxy!) это режим доступа к данным.
  • Вкладки Аутентификации выставляем BasicAuth, остальные не отмеченные
  • Basic Auth Details указываем в соответствии с теми, которые прописывали при развёртывании НОКа (по умолчанию пользователь readonly)

Проверить настройки можно кнопкой "Test Connection". После нажимаем Save. Наслаждаемся эффектом.

Image Added

Добавление своих метрик
Anchor
add_variable_metric
add_variable_metric

Для добавления метрики необходимо выполнить 2 шага:

  1. Создать метрику (Metric Type) (выполняется в веб-интерфейсе)
  2. Написать её конфигурацию (выполняется на активаторе)

Перед добавлением метрики есть 2  пути. Если метрика более менее стандартная (температура, загрузка процессора, интерфейсная) то можно клонировать существующую. В остальных случаях необходимо будет ответить на несколько вопросов:

  1. Необходимо понять, какие ключевые поля будут участвовать в сборе метрики. На этот вопрос можно не отвечать когда:
    • н-р, необходимо снимать интерфейсные метрики (они уже реализованы), копируем, вносим пару изменений и пользуем
    • метрика всегда одна (н-р один процессор на железке и больше быть не может или количество пользователей)
  2. В случае SNMP - всё просто. Открываем её в SNMP браузере и ключевые поля перечислены там. Ищем подходящий MetricScope или создаём свой.
  3. В случае CLI свободы больше. Надо подумать, какие имена/значения будут отличать метрику для данного объекта от других.
Info

Если метрика относится к параметру объекта (н-р показатель какого-нибудь датчика) - используем Environment, если метрика для интерфейса (н-р размер входящего буфера) - то scope interface. Имя задаётся через прямую черту: | это позвляет отстраивать иерархию метрик. Рекомендуется пользоваться данным соглашением


Добавлени MetricTypes

После выбора Metric Scope идём в интерфейс создания метрики: PM -> Setup -> Metric Type. И нажимаем на кнопку Добавить, заполняем поля:

Image Added

Image Added

  • Name - имя метрики. Желательно давать осмысленные имена и использовать иерархию (она строится через вертикальный полосы)
  • Scope - выбранный на предыдущем этапе MetricScope
  • FieldName - имя столбца в таблице БД (маленькие буквы, только буквы и нижнее подчёркивание), должно быть уникально в пределах Scope
  • FieldType - тип столбца в таблице БД (выбирать необходимо внимательно т.к. поменять можно будет только с удалением таблицы)
    • Int* - целое число (8, 16, 32 бита)
    • UInt - целое число без знака (положительное)
    • Float* - число с запятой (десятичное)
    • String - строка
  • Measure - единица измерения. 
    • packet/s
    • bit/s
    • C
    • mA
    • dBm
    • %

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

Настройка метрики на сборщике (активаторе)

В задаче активатору приходит список метрик (в виде имён), в зависимости от способа их получения: SNMP или не SNMP дальнейший путь расходится.

За формирование списка OIDов для съёма отвечает генератор. Для объяснения ему что к чему необходимо написать конфигурацию.
Конфигурация метрики:

  • формат: JSON
  • место хранения: директория snmp_metrics профиля
  • потребитель: генератор OID
  • не требуется: если получение метрики не по SNMP
  • пример файла настройки:
Code Block
languagejs
themeEmacs
{
  "$metric": "CPU | Usage",
  "$type": "oid",
  "oid": "1.3.6.1.4.1.2011.2.23.1.18.1.3.0",
  "type": "gauge",
  "scale": 1
}
  • $metric - Имя метрики, обязательное поле. Должно совпадать с именем, созданным в интерфейсе Metric Type
  • $type - Имя генератора, обязательное поле. Обозначает алгоритм по которому будут создаваться SNMP OID для считывания.
  • oid - SNMP OID или его шаблон, который будет собираться для метрики
  • type - тип SNMP (gauge, counter, bool). Если не указан, то подразумевается gauge
  • scale - множитель может быть целым числом (в этому случае полученное значение умножается на это число) или фцнкцией, тогда число передаётся ей для обработки.
  • Дополнительные параметры (определяются конкретным генератором)
Info

Формулы для Scale можно написать в "<noc>/core/script/metrics.py".

Code Block
languagepy
themeEmacs
titleScale functiion
collapsetrue
def percent(value, total):
    """
    Convert absolute and total values to percent
    """
    if total:
        return float(value) * 100.0 / float(total)
    else:
        return 100.0

def percent_one(value, total):
    """
    Convert absolute and total values to percent
    """
    if total:
        return float(value) * 100.0 / (float(total) + float(value))
    else:
        return 100.0


Генераторы

Отвечают за формирование списка SNMP OIDов для сбора устройства на основе файла конфигурации. Указываются в директиве "$type" конфига.

В базовой системы реализованы следующие генераторы:

OID

Считывает OID, заданный в конфиг файле. Доступны параметры type и scale.

Code Block
languagejs
{
  "$metric": "CPU | Usage",
  "$type": "oid",
  "oid": "1.3.6.1.4.1.8886.1.1.1.4.1.0"
}

Может указать больше 1 OID’a, но должна быть задана функция, для рассчёта значения метрики:

Code Block
languagejs
{
  "$metric": "Memory | Usage",
  "$type": "oid",
  "oid": [
    "1.3.6.1.4.1.2021.4.5.0",
    "1.3.6.1.4.1.2021.4.6.0"
  ],
  "scale": "percent_usage"
}


Info
Сами функции находят в файле core/script/metrics.py
percent_usage(value, total):
percent_invert(value, total):
sum(*args):
subtract(*args):
is1(x):

OIDS

Позволяет перечислять OID’ы списком с указанием path. Полезен, если метрика векторная, но сами значения наперёд известны и неизменны.

Пример конфиг файла:

Code Block
languagejs
{
  "$metric": "Environment | Sensor Status",
  "$type": "oids",
  "oids": [{
    "oid": "1.3.6.1.4.1.41752.5.15.1.1.0",
    "path": ["","","", "Door"],
    "$type": "oid",
    "type": "gauge",
    "scale": 1
  },{
    "oid": "1.3.6.1.4.1.41752.5.15.1.7.0",
    "path": ["","","", "Key_State"],
    "$type": "oid",
    "type": "gauge",
    "scale": 1
  }
  ]}

Здесь появляется дополнительное свойство - path. Его формат можно уточнить в MetricScope. Например, для Environment будут:

  • chassis
  • slot
  • module
  • name


Image Added

CAPS

Специфичный генератор. Проверяет Capabilities, если присутствует - отрабатывает соответствующее правило
! для платформы и версии

CAPINDEX и CAPLIST

При налачии capabilities в специальном формате, позволяет сгенерировать SNMP OID по шаблону.
Capindex - Caps в виде числа, Caplist в виде чисел, разделённых символом.

MATCHERS

Реализует возможность выбора SNMP OIDов на основании платформы/версии ПО оборудования через конфигурацию. Конфигурация для метрик распологается в файликах из папки snmp_metrics профиля. Теперь в них можно применять генератор match:

Code Block
languagejs
{
   "$metric": "XXXXX",
   "$type": "match",
   "$matchers": {
     // Локальные матчеры
     // По возможности стоит выносить в платформы
     "is_3328": {
      "platform": {
        "$regex": "3328"
            }
        },
      "is_2328": {
      "platform": {
        "$regex": "2328"
            }
        }
    }
    },
   "$match": [
        {
            "$match": "is_3328",  // Попадает только если сработал матчер из $matchers или из профиля (if getattr(self, name))
            "$type": "oid",
            "..."
        },
        {
           // Нет матчера, срабатывает всегда
            "$type": "oid",
            ...
        }
   ]
   }
}

Блок matchers описывает структуру по которой будет проходить проверку версия и платформа оборудования. На выходе будет совпало или нет. Сами OIDы описываются в разделе $match в виде списка. При работе проходим последовательно список и производим проверку соотв матчера из блока matchers.

  • если совпадение есть - берём данный OID (проверяется матчер, указанный в параметре “$match”),
  • если нет - идём дальше.
  • если совпадений не было - будет использован блок без $match (по-умолчанию он идёт последним)

Внутри можно использовать такие же генераторы, как и в обычных конфигурациях.

Н-р для профиля Huawei.VRP есть стековая серия коммутаторов - 5328, коммутаторы доступа 2328 и остальные. Для стэков есть отдельные OID на каждый коммутатор в стеке и процессор в нём. Для 2328 используюется устаревшая ветка OID. Поэтому, получаем:

Code Block
languagejs
{
  "$metric": "CPU | Usage",
  "$type": "match",
  "$matchers": {
    "is_5328": {
      "platform": {
        "$regex": "5328"
            }
        },
    "is_2328": {
      "platform": {
        "$regex": "2328"
            }
        }
    },
  "$match": [{
    "$match": "is_2328",
    "oid": "1.3.6.1.4.1.2011.2.23.1.18.1.3.0",
    "path": ["","","", "Current_Load"],
    "$type": "oid",
    "type": "gauge",
    "scale": 1
  },{
    "$match": "is_5328",
    "$type": "slot",
    "oid": "1.3.6.1.4.1.2011.6.3.4.1.2.{{ hwSlotIndex }}"
   },{
    "$type": "oid",
    "oid": "1.3.6.1.4.1.2011.6.3.4.1.3.0.0.0",
    "type": "gauge",
    "scale": 1
  }]
}

Генератор профиля

Есть возможность написать свой генератор, если не подходит какой-либо из стандартных. Конфиг, при этом выглядит так:

Code Block
languagejs
{
  "$metric": "CPU | Load | 1min",
  "$type": "slot",
  "oid": "1.3.6.1.4.1.2011.6.3.4.1.3.{{ hwSlotIndex }}"
}

В данном случае в качестве OID’a записывается шаблон. Заместо переменной {{ hwSlotIndex }} будет подставлено значение из генератора. В поле $type записывается имя созданного генератора (уникально в пределах профиля). Сам генератор помещается в скрипт get_metrics соответствующего профиля. Н-р:

Code Block
languagepy
from noc.sa.profiles.Generic.get_metrics import Script as GetMetricsScript
from noc.sa.profiles.Generic.get_metrics import OIDRule
from noc.core.mib import mib

class SlotRule(OIDRule):
    # Имя генератора, должно совпадать с параметром $type в конфиге
    name = "slot"

    def iter_oids(self, script, metric):
        """
        Основной метод, должен вернуть переменные для подстановки в шаблон и путь (path)
        """
        sysSlotIndex = [0]
        i = 1
        r = {}
        # Здесь мы используем значение CAPS для определения правильного числа коммутаторов в стэке
        if script.has_capability("Stack | Member Ids"):
            sysSlotIndex = [int(index) for index in script.capabilities["Stack | Member Ids"].split(" | ")]
        elif script.has_capability("Stack | Members"):
            # Индексы коммутаторов в стеке делаем списком
            sysSlotIndex = range(1, script.capabilities["Stack | Members"] + 1)
        else:
            sysSlotIndex = [1]

        for ms in sysSlotIndex:
            r[str(i)] = "%d" % ms
            # r[str(i)] = {"healthModuleSlot": ms}
            i += 1

        for i in r:
            """
            В цикле обходим индексы и формируем переменную `hwSlotIndex`, для получения нормального OID'a используем метод `self.expand` передавая ему словарь с переменными и шаблон OID (`self.oid`)
            """
            if self.is_complex:
                # Это проверка на наличие нескольких OID (если их необходимо передавать в функцию для расчёта)
                gen = [mib[self.expand(o, {"hwSlotIndex": r[i]})] for o in self.oid]
                path = ["0", "0", i, ""] if "CPU" in metric.metric else ["0", i, "0"]
                if gen:
                    # self.type и self.scale - берутся из конфига. При необходимости, можно задавать другие параметры и получать к ним доступ здесь
                    yield tuple(gen), self.type, self.scale, path
            else:
                oid = mib[self.expand(self.oid, {"hwSlotIndex": r[i]})]
                path = ["0", "0", i, ""] if "CPU" in metric.metric else ["0", i, "0"]
                if oid:
                    yield oid, self.type, self.scale, path


Сбор метрик по CLI

В случае сбора метрик по CLI необходимо писать реализацию полноценного скрипта get_metrics для работы по CLI.

Для примера, возьмём скрипт сбора сессий пользователей для профиля Juniper.JunOSe

Code Block
languagepy
from noc.sa.profiles.Generic.get_metrics import Script as GetMetricsScript
from noc.lib.text import parse_table

class Script(GetMetricsScript):
    name = "Juniper.JUNOSe.get_metrics"

    CLI_METRICS = set(["Subscribers | Summary"])
    # Полезно указывать, какие метрики скрипт может собирать. Это исключит его запуск при сборе других метрик.

    def collect_profile_metrics(self, metrics):
        # Основной метод. При вызывается при старте скрипта 
        if self.has_capability("BRAS | PPTP"):
            self.logger.debug("Merics %s" % metrics)
            # Проверяем, что есть соответствующий CAPS и метрики, которые мы можем собрать
            if self.CLI_METRICS.intersection(set(m.metric for m in metrics)):
                # Запускаем функцию сбора. Делить скрипт на функции необязательно, но полезно для удобочитаемости
                self.collect_subscribers_metrics(metrics)

    def collect_subscribers_metrics(self, metrics):
        # if not (self.ALL_SLA_METRICS & set(metrics)):
        #     return  # NO SLA metrics requested
        ts = self.get_ts()
        # Получаем время (timestamp) и запускаем функцию сбора значений метрик с устройства
        m = self.get_subscribers_metrics()
        for bv in metrics:
            # обходим метрики (в данной переменной содержатся все метрики переданные для сбора)
            if bv.metric not in self.CLI_METRICS:
                # Если мы не можем собирать метрику - то пропускаем
                continue
            for slot in m:
                # set_metrics передаёт собранную метрику для отдачи дискавери.
                self.set_metric(
                    id=bv.id,
                    metric=bv.metric,
                    value=m[slot],
                    ts=ts,
                    path=["0", slot, ""]
                )

    def get_subscribers_metrics(self):
        """
        Returns collected subscribers metric in form
        slot id -> {
            rtt: RTT in seconds
        }
        :return:
        """
        v = self.cli("show subscribers summary slot")
        v = v.splitlines()[:-2]
        v = "\n".join(v)
        r_v = parse_table(v)
        if len(r_v) < 3:
            return {}
        # r = defaultdict(dict)
        r = dict(r_v)
        return r


Что-то пошло не так (Отладка)

Возможно разное. Если после выполненных настроек красивые графики не появились, или, внезапно, канули в болото - необходимо разобраться в причинах и починить.

Для выяснение причин отсутствия графиков имеет смысл повторно пройти все этапы настройки и проверить, не пропущена ли где запятая. Если таковую найти не удалось - идём проверять по порядку участия в PM:

Проверка выполненных настроек и дискавери.

Для начала, необходимо заглянуть в лог периодик дискавери. Проверить дату последнего запуска и заглянуть в лог. При нормальной работе там можно увидеть:

No Format
|metrics]  Collecting metrics
|metrics]  SLA not configured, skipping SLA metrics
|metrics]  SLA metrics are not configured. Skipping
|metrics]  Spooling 14 metrics

Если при этом метрик мы не видим (на графиках), то смотрим в сторону писателя (chwriter) и интерфейса графаны.

Если мы видим что-то, навроде этого:

No Format
|metrics]  Collecting metrics
|metrics]  SLA not configured, skipping SLA metrics
|metrics]  SLA metrics are not configured. Skipping
|metrics]  No metrics found

No metrics found - То имеет смысл пойти разбираться что не так в плане доступа к устройству по SNMP.

Если же мы видим слова:

  • Interface metrics are not configured. Skipping - необходимо проверить назначены ли метрики на профили интерфейсов и профили интерфейсов на интерфейсы
  • SLA not configured, skipping SLA metrics - проверить профили SLA

Проверка реквизитов доступа.

Необходимо проверить, что устройство доступно с активатора по SNMP. Это делается путём запуска скрипта

Code Block
languagebash
#./noc script get_uptime MONAME

Если с устройства успешно считался Uptime, то доступ по SNMP есть. И необходимо проверить capabilities на страничке с устройством.

Мы всё сделали, а данных таки нет. Попробуем выяснить - в каком месте может возникнуть проблема.

Проверка работы дискавери

Проверка работы дискавери осуществляется командой: 


Code Block
languagebash
#./noc discovery --debug run periodic MONAME


У неё достаточно длинный вывод, в нём необходимо зафиксировать несколько моментов:

  • metrics] Collecting metrics: - после неё идёт перечень метрик, запрашиваемых с активатора
  • [sae] [CALL<] sae.get_credentials (24.18ms), [activator-KAMCHATKA] [SYNC CALL>] - после идёт перечень реквизитов доступа, отправленных на активатор. Необходимо проверить community и поддерживаемые версии SNMP (v1, v2 …)
  • metrics] [Interface | Packets | Out||||Ethernet1/28] Old value: 8.88965844237e+18@1509298271847603200, new value: 8.89067827806e+18@1509300231354959104показатель того, что новые значения получены и идёт расчёт метрик
  • |metrics] Spooling 154 metrics - количество собранных метрик
  • |metrics] 0 alarms detected - отработка порогов
  • Отправляемы метрики
No Format
Collected CH data:
Fields: %s interface.date.ts.managed_object.path.discards_out.errors_in.load_in.load_out.status_oper
2017-10-30      2017-10-30 04:03:51     6119069133381749519     ['','','','Ethernet1/16']       0       0       56209   2822339 1
Fields: %s memory.date.ts.managed_object.usage
2017-10-30      2017-10-30 04:03:51     6119069133381749519     95

Проверка писателя.

Достаточно заглянуть в его лог. Там должны быть сообщения о записи метрик:

No Format
[chwriter] [interface.date.ts.managed_object.path.discards_in.errors_out.load_in.load_out.packets_in.packets_out.status_admin.status_oper] 58 records sent in 11.94ms
[chwriter] [ping.date.ts.managed_object.rtt.attempts] 86 records sent in 2.75ms
[chwriter] [interface.date.ts.managed_object.path.discards_out.errors_in.load_in.load_out.status_oper] 215 records sent in 9.37ms
[nsq.client] [stage-wrk:4150:chwriter:chwriter] received heartbeat
[chwriter] Feeding speed: 38.10records/sec, active channels: 11, buffered records: 284
[chwriter] [memory.date.ts.managed_object.path.usage_5s] 1 records sent in 5.35ms
[chwriter] [cpu.date.ts.managed_object.path.load_5s] 1 records sent in 2.81ms

Если есть какие-то проблемы с записью в БД в логе будут ругательные сообщения.

Проверка CH

Для этого необходимо подключиться к БД и повыполнять запросы к данным.
Команда для подключения: 

Code Block
languagebash
clickhouse-client -h 0.0.0.0, если не настрены права, или clickhouse-client -u USERNAME --password PASSWORD -h 0.0.0.0
Далее:
:) use noc
:) show tables
:) select * from interface order by ts desc limit 10


Посмотреть отображаются ли данные и время последних записей. Если в данных пусто, а лог писателя говорит что они записаны… То необходимо подсмотреть в логе сервера ClickHouse

Отладка скрипта сбора метрик

Чтобы проверить, нет ли ошибки в скриптах, можно воспользоваться механизмом отладки, только, дополнительно передать в скрипт парметры. Делается это так:

Code Block
languagebash
# ./noc script --debug Cisco.IOS.get_metrics "xxx-sw61" metrics:='[{"metric": "Environment | Voltage", "id": 0}]'
.....
 Result: [{'scale': 1.0, 'name': 'Memory | Usage', 'tags': {'object': None}, 'ts': 1469865495320386816, 'value': 49.583421519590374, 'type': 'gauge'}]


Уточнения