Описание
Подсистема Performance Management (PM) в ноке отвечает за сбор метрик с оборудования (дискавери) и контроль их значения (пороги, threshold).
Умеет из коробки:
- Собрать (collect) метрики по SNMP OID (по интерфейсам и не векторные метрики);
- Записать, или не записать, метрики в БД ClickHouse (возможна поддержка других БД, писатель есть только для CH);
- Отобразить метрики при помощи Графаны (Grafana);
- Пороги - создать аварию по превышению некоторого значения (или значения функции) за интервал времени
Умеет после использования напильника:
- собрать метрики по CLI (надо писать код сборщика);
- самые разные метрки по SNMP (для сложных случаев необходимо писать
генератор
); - можно делать свои дашборды в Графане
- и всякую аналитику по метрикам в CH (необходимо написание запросов руками)
Следует признать, что PM находится в стадии развития. Заложены широкие возможности, но много требует доработки или реализации. Посмотрим на то, что есть сейчас.
Архитектура и компоненты
Архитектурно PM состоит из источника данных, сборщика (коллектора), транспорта, писателя и хранилища. Туда же, можно добавить интерфейс для отображения графиков и интерфейс для аналитики (отчётов).
- Источник данных может быть внешний (устройство) или внутренний (пингер, дискавери)
- В качестве сборщика выступает активатор. Инициатором сбора - дискавери. Т.е. со стороны дискавери приходит запрос на активатор, он отрабатывается и возвращает результат дискавери, который уже отправляет его в сторону писателя по транспорту.
- Транспортом для метрик выступает HTTP (между дискавери и активатором) и NSQ во всех остальных случаях.
- Писатель отвечает за запись дошедших до него метрик в Хранилище. Для каждого хранилища свой писатель.
- Хранилищем выступает СУБД ClickHouse от Yandex (CH).
- Интерфейс для графиков - Grafana.
Пройдёмся по компонентам подробнее:
Активатор
Запускает скрипты для сбора метрик.
Generic.get_metrics
В ней присутствуют JSON фалйы со специфичными для профиля метрики SNMP (н-р OID’ы для памяти и процессора) соответствующего профиля. Для добавления своих метрик, необходимо добавить файлик с ними в папку snmp_metrics. Подробнее вопрос будет рассмотрен далее.- реализация сбора метрик по SNMP, поскольку является платформо-независимой. Работа скрипта определяется конфиг-файлами, расположенными в папках
snmp_metrics
профиля.
Profile.get_metrics - реализует различные платформо-зависимые вещи: сбор метрик по CLI и генераторы OID'ов
get_capabilities - напрямую в сборе метрик не участвует, но определяет поддержку оборудованием протокола SNMP и различных ньансов работы с ним (поддержку bulk, ). В случае отсутствия поддержки SNMP, сбор метрик запускаться не будет.
- get_interfaces - сам по себе в сборе метрик не участвует. Но он необходим в случае сбора метрик с интерфейсов, т.к. возвращает ifindex. Если не будет ifindex, то не будет метрик с интрейсов.
Дискавери
За сбор метрик отвечает Periodic дискавери. Его задачи:
- В заданное время озадачить активатор сбором метрики
- Отработать пороги, согласно правилам (создать аварию, по необходимости)
- После получения метрик упаковать их для отправки по NSQ.
- Поместить в очередь metrics, откуда их заберёт писатель.
Центральная штука, в общем.
NSQD aka транспорт
ПО очереди для работы в реальном времени с гарантированной первой доставкой. Занимается передачей сообщений из одного конца очереди в другой. NSQD необходим в одном экземпляре на каждую ноду, NSQLOOKUPD минимум 1 (2 для отказоустойчивости).
Архитектурно NSQD состоит из 3 компонент: 2 обязательных и 1 опционального.
- процесс NSQD отвечает за работу очередей: принимает сообщения и передаёт их к месту назначения. Должен присутствовать на каждой НОДе, где есть процесс, пишущий в очередь. В случае невыполнения требования возможны потери сообщений.
- процесс NSQLOOKUPD отвечает за поиск демонов NSQD с необходимыми топиками (очередями с сообщениями). Необходим по крайней мере в 1 экземпляре.
- процесс NSQADMIND Это админка, к NSQD не обязательна, но позволяет просматривать различную статистику и управлять очередями (очищать, удалять и т.д.)
CHWRITER
Слушает приходящие сообщения (канал metrics
) и, по мере их накопления, записывает в БД. Интервал записи поддаётся настройке. Рекомендуется держать его поближе к БД.
ClikcHouse (CH)
В качестве хранилища для метрик используется БД Clickhouse
от Yandex
Сущности
Метрика - некоторая изменяющаяся во времени величина, подлежащая фиксации. Формально говоря, метрикой может быть любая величина: скорость интерфейса, число свободной памяти, статус интерфейса и т.д. Достаточно, чтобы она менялась во времени и представляла какой-то интерес.
Метрики бывают:- Скалярные - когда одной метрике соответствует одно значение. Н-р если у устройства 1 датчик температуры, то метрике
Температура
будет соотв. 1 значение - показатель этого датчика. Если же, датчиков несколько, то необходимо будет создавать метрикиТемпература датчика 1
,Температура датчика 2
и т.д. - Векторные - когда одной метрике соответствует более одного значения. Н-р метрике Кол-во входящих пакетов соответствует столько значений, сколько интерфейсов на устройстве. Рядом с векторными метриками идёт понятие
Path
, рассмотрено ниже.
- Скалярные - когда одной метрике соответствует одно значение. Н-р если у устройства 1 датчик температуры, то метрике
К основным понятиям PM в НОКе добавляет несколько своих:
- MetricScope (пространство метрик) - множество метрик, объединённых некоторой общей характеристикой (
ключевыми полями
). Ближайший пример - это интерфейсные метрики, объединённые индексом интерфейса или н-р датчики оборудования, объединённые местом в устройстве или номером. Физическое представлениеscope
, это таблица в которую идёт запись метрик, ему принадлежащих, с индексом поключевым полям
. - MetricType - наименование метрики. Принадлежит какому либо пространству
MetricScope
. Физическое представление - столбец в таблице (название таблицы вmetric_scope
) - Path - Необходим для векторных метрик. Служит для детализации метрики в пределах объекта. Н-р, может содержать индекс датчика, номер слота памяти и т.д. Точное соответствие полей задаётся в
MetricScope
, сам передаётся списком.
Байки от разработчика
Байки от разработчика:
Представим, что у вас есть нетрезвый электрик, совковый такой, прям небритый, в кепке и с перегаром. По имени Петрович. И у него есть щиток, в котором 3 фазы.
А вы – начальник электрика Петровича со щитком, в котором 3 фазы. И вольтметром.
И, раз в 5 минут, посылаете его за щитком, мерять напряжение. Которое он пишет на бумажке и отдаёт вам. А вы рисуете по бумажке график. Чтобы все видели, вот.
Прибор у Петровича выдаёт метрику, допустим, Environment | Voltage
, а фаз 3. Петрович добивает 0.33, поправляет кепку, идет, и пишет карандашиком на бумажке:
Environment | Voltage [“фаза1”] 222.3
Environment | Voltage [“фаза2”] 220.7
Environment | Voltage [“фаза3”] 222.7
Итого, имеем:
- Небритый электрик
- 3 фазы
- 1 вольтметр
Environment | Voltage [“фаза1”] 222.3
,Environment | Voltage [“фаза2”] 220.7
,Environment | Voltage [“фаза3”] 222.7
Тепрерь представьте, что по пути он встретил Прасковью… и она говорит, что у нее тоже напряжение. Петрович поправляет кепку и пишет Environment | Voltage [“Прасковья”] 218.4
.
Итого:
- Небритый электрик
- 3 фазы
- 1 вотльтметр
- Прасковья
Environment | Voltage [“фаза1”] 222.3
,Environment | Voltage [“фаза2”] 220.7
,Environment | Voltage [“фаза3”] 222.7
,Environment | Voltage [“Прасковья”] 218.4
Но тут вы, находите в запасниках стола температуру, которую меряют градусником! и будет у вас вторая метрика Environment | Temperature
. Петровича послали мерять её тоже. Он так и запишет - [“Щитовая”]
, [“Прасковья подмышка”]
, [“Прасковья ad-rectum"]
Резюме: Metric Type
на вольтаж у тебя один, на температуру - еще один, где бы Петрович их не замерял: Environment | Wodka [“Петрович”] 0.33
или Environment | Drink [“Водка”, “Петрович”]
, а путь
(Path
) до них разный…
- Генератор - потребен при сборе векторных метрик по SNMP. Реализует интерфейс
дискавери
метрик, раскладывая базовый SNMP OID на OID’ы по которым пойдёт сбор данных. Самый простой пример - это создание из OID’а кол-ва прошедших байт через интерфейс OID’ов для каждого интерфейса. Н-р базовый OID для входящих пакетов на интерфейс (ifInUcastPkts):1.3.6.1.2.1.2.2.1.11
, чтобы снять эту метрику для конкретного интерфейса к нему необходимо дописать его номер:1.3.6.1.2.1.2.2.1.11.2
, вот этим и занимаются генераторы. Подробнее, рассмотрены в разделе добавления метрик.
Настройка сбора метрик
Прервём поток букв и попробуем снабдить их картинками. В текущей реализации настройку сбора метрик очень упростили. Фактически, необходимо:
- Необходимо добавить метрики для сбора:
- Интерфейсные метрики добавляются в профиле интерфейса (Interface Profile): Inventory -> Setup -> Interface Profile (вкладка Metrics)
- Метрики объекта в профиле объекта (Object Profile): Service Activation -> Setup -> Object Profile(вкладка Metrics)
- Метрики SLA в профиле SLA (SLA Profile): SLA -> Setup -> SLA Profile
- Для интерфейсных метрик необходим работающий дискавери интерфейсов и назначить профили на интерфейсы, с которых необходимо собираться метрики. Автоматизации этого процесса посвящена статья
- Для SLA метрик необходим SLA дискавери и нзначить профиль SLA на необходимую пробу (пробы собираются SLA дискавери).
- Для снятия метрик по SNMP, необходим прописанный и рабочий
SNMP_RO
community в настройках объекта или назначенный профиль аутентификации с ним.
В случае, если назначен профиль аутентификации (Auth Profile) на устройство, то будет использован он, даже если поле SNMP RO
в нём пустое (в этом случае система будет писать, что отсутствует community)
- Активировать Periodic Discovery и включить в нём сбор метрик: Service Activation -> Setup -> Object Profile, Periodic -> Metric
- Настроить пороги (опционально)
Пройдёмся по этим шагам подробнее:
Настрока Managed Object
Необходимо проверить ManagedObject:
- SNMP Community необходим прописанный Communtiy RO (либо указан в назначенный Профиль аутентификации (AuthProfile)) в случае снятия метрик по SNMP.
В случае, если назначен профиль аутентификации (Auth Profile) на устройство, то будет использован он, даже если поле SNMP RO
в нём пустое (в этом случае система будет писать, что отсутствует community)
- На вкладке Capabilities, необходимо убедиться, что проверка SNMP на устройстве завершилась успешно (правый скриншот). Вкладка Capabilities (Возможности) заполняется по итогам работы опроса Caps:
- 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 - сохранять метрику в БД
- По необходимости, указываем пороги (описаны в разделе ниже)
После, переходим на вкладку "Periodic Discovery" и активируем сбор метрик (устанавливаем галочка Enable и Metric). По необходимости, настраиваем интервал обхода.
Настройка сбора метрик с интерфейсов
Метрики для интерфейсов настраиваются в Inventory -> Setup -> "Interface Profiles". В нём необходимо аналогично Managed Object Profile добавить метрики.
После этого привязать профиль к интерфейсам. Это можно сделать в меню Inventory -> Interfaces. Необходимо в выпадающем списке выбрать MO и назначить профили. В это же меню можно попасть по кнопке Interfaces из "Service Activation" -> "Managed Object" -> <MO>.
Настройка Interfaces Classification Rules
Делается опционально-обязательно. Предназначены для автоматического назначения профила интерфейса на интерфейс. Конечно, можно вручную устанавливать профили интерфейсов, но это не продуктивно Поэтому можно расписать правила классификации. Делается это из меню Inventory -> Setup -> "Interface Classification Rule".
Подробно работа с правилами расписана тут: Классификация интерфейсов.
Настройка Dashboard
Просмотр метрик идёт через Dashboard. Он доступен из интерфейса MO: в этом случае, он, автоматически, настраивается на отображение всех метрик, собираемых с данного MO или по адресу https://<AddressNOCWeb>/ui/grafana:
Если в интерфейсе Графаны вместо в значениях метрик выводится случайная величина: необходимо проверить настройки источника данных (DataSource) в графане.
Для настройки Источника данных (DataSource) необходим админский доступ к Графане (по умолчанию, он у пользователя admin). В левом верхнем углу кликнуть по значку графаны, далее опция "Data Sources". После этого нажать кнопку Add в верхнем меню.
При добавлении указываем следующие опции:
- Name (может быть любой)
- Обязательно указываем галочку Default (по умолчанию)
- Type выбираем ClickHouse (или близкую к ней)
- В URL - адрес ClickHouse (если стоит на отдельном хосте - то необходимо указать адрес этого хоста), порт 8086 - по умолчанию
- Access - Proxy (не путать с http_proxy!) это режим доступа к данным.
- Вкладки Аутентификации выставляем BasicAuth, остальные не отмеченные
- Basic Auth Details указываем в соответствии с теми, которые прописывали при развёртывании НОКа (по умолчанию пользователь readonly)
Проверить настройки можно кнопкой "Test Connection". После нажимаем Save. Наслаждаемся эффектом.
Добавление своих метрик
Для добавления метрики необходимо выполнить 2 шага:
- Создать метрику (Metric Type) (выполняется в веб-интерфейсе)
- Написать её конфигурацию (выполняется на активаторе)
Перед добавлением метрики есть 2 пути. Если метрика более менее стандартная (температура, загрузка процессора, интерфейсная) то можно клонировать существующую. В остальных случаях необходимо будет ответить на несколько вопросов:
- Необходимо понять, какие ключевые поля будут участвовать в сборе метрики. На этот вопрос можно не отвечать когда:
- н-р, необходимо снимать интерфейсные метрики (они уже реализованы), копируем, вносим пару изменений и пользуем
- метрика всегда одна (н-р один процессор на железке и больше быть не может или количество пользователей)
- В случае SNMP - всё просто. Открываем её в SNMP браузере и ключевые поля перечислены там. Ищем подходящий
MetricScope
или создаём свой. - В случае CLI свободы больше. Надо подумать, какие имена/значения будут отличать метрику для данного объекта от других.
Если метрика относится к параметру объекта (н-р показатель какого-нибудь датчика) - используем Environment
, если метрика для интерфейса (н-р размер входящего буфера) - то scope interface
. Имя задаётся через прямую черту: |
это позвляет отстраивать иерархию метрик. Рекомендуется пользоваться данным соглашением
Добавлени MetricTypes
После выбора Metric Scope
идём в интерфейс создания метрики: PM
-> Setup
-> Metric Type
. И нажимаем на кнопку Добавить
, заполняем поля:
- 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
- пример файла настройки:
{ "$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
- множитель может быть целым числом (в этому случае полученное значение умножается на это число) или фцнкцией, тогда число передаётся ей для обработки.- Дополнительные параметры (определяются конкретным генератором)
Формулы для Scale можно написать в "<noc>/core/script/metrics.py".
Генераторы
Отвечают за формирование списка SNMP OIDов для сбора устройства на основе файла конфигурации. Указываются в директиве "$type" конфига.
В базовой системы реализованы следующие генераторы:
OID
Считывает OID, заданный в конфиг файле. Доступны параметры type
и scale
.
{ "$metric": "CPU | Usage", "$type": "oid", "oid": "1.3.6.1.4.1.8886.1.1.1.4.1.0" }
Может указать больше 1 OID’a, но должна быть задана функция, для рассчёта значения метрики:
{ "$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" }
Сами функции находят в файле core/script/metrics.py
percent_usage(value, total):
percent_invert(value, total):
sum(*args):
subtract(*args):
is1(x):
OIDS
Позволяет перечислять OID’ы списком с указанием path
. Полезен, если метрика векторная, но сами значения наперёд известны и неизменны.
Пример конфиг файла:
{ "$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
CAPS
Специфичный генератор. Проверяет Capabilities, если присутствует - отрабатывает соответствующее правило
! для платформы и версии
CAPINDEX и CAPLIST
При налачии capabilities в специальном формате, позволяет сгенерировать SNMP OID по шаблону.
Capindex - Caps в виде числа, Caplist в виде чисел, разделённых символом.
MATCHERS
Реализует возможность выбора SNMP OIDов на основании платформы
/версии
ПО оборудования через конфигурацию. Конфигурация для метрик распологается в файликах из папки snmp_metrics
профиля. Теперь в них можно применять генератор match
:
{ "$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. Поэтому, получаем:
{ "$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 }] }
Генератор профиля
Есть возможность написать свой генератор, если не подходит какой-либо из стандартных. Конфиг, при этом выглядит так:
{ "$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
соответствующего профиля. Н-р:
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
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:
Проверка выполненных настроек и дискавери.
Для начала, необходимо заглянуть в лог периодик дискавери. Проверить дату последнего запуска и заглянуть в лог. При нормальной работе там можно увидеть:
|metrics] Collecting metrics |metrics] SLA not configured, skipping SLA metrics |metrics] SLA metrics are not configured. Skipping |metrics] Spooling 14 metrics
Если при этом метрик мы не видим (на графиках), то смотрим в сторону писателя (chwriter
) и интерфейса графаны.
Если мы видим что-то, навроде этого:
|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. Это делается путём запуска скрипта
#./noc script get_uptime MONAME
Если с устройства успешно считался Uptime, то доступ по SNMP есть. И необходимо проверить capabilities
на страничке с устройством.
Мы всё сделали, а данных таки нет. Попробуем выяснить - в каком месте может возникнуть проблема.
Проверка работы дискавери
Проверка работы дискавери осуществляется командой:
#./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
- отработка порогов- Отправляемы метрики
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
Проверка писателя.
Достаточно заглянуть в его лог. Там должны быть сообщения о записи метрик:
[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
Для этого необходимо подключиться к БД и повыполнять запросы к данным.
Команда для подключения:
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
Отладка скрипта сбора метрик
Чтобы проверить, нет ли ошибки в скриптах, можно воспользоваться механизмом отладки, только, дополнительно передать в скрипт парметры. Делается это так:
# ./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'}]