
Частый кейс в промышленной инженерии — предположим, понадобилось снимать телеметрию с управляемых iPDU в стойке. Стандартный маршрут включает виртуалку под Zabbix, рядом SQL‑база, сверху веб‑интерфейс, дальше по вкусу облако и оплата за хранение данных. В этом кейсе другой стек — Telegraf, InfluxDB и Grafana — целиком внутри промышленного одноплатника, который сидит в той же стойке, что и опрашиваемое оборудование, потребляет несколько ватт и настраивается из браузера с рабочего места.
Дисклеймер. Эта статья родилась из практического кейса поиска неисправностей и не претендует на академичность и полноту. Показан подход, инструменты, выход на результат, личные и субъективные выводы. Заранее прошу прощения, что статья получилась очень длинная, и спасибо всем, кто прочтет.
В этом кейсе стенд собрали с практической целью, стояла задача от клиента — он жаловался на отказы в сборе данных. Надо было выявить неочевидную неисправность — при длительном непрерывном опросе SNMP‑агент PDU начинал терять запросы. Термин PDU здесь и далее означает Power Distribution Unit (блок распределения питания или иными словами, блок силовых розеток).
Обычная система мониторинга с интервалом в пять минут ничего подозрительного не показала, поэтому мы настроили наш стенд под опрос 1 раз в 10 секунд. Забегая вперед, скажем сразу, что все кончилось хорошо, проблему мы нашли и она была не в оборудовании — а в том, что в нескольких устройствах задублировались МАК‑адреса, что было пофиксено обновлением прошивки.
Дальше опишу сборку стенда, разбор формата таблиц устройства электропитания Exagate и результаты прогона.
Стенд, оборудование и версии ПО
Объект мониторинга — управляемый iPDU Exagate серии POWERGuard2, модель PWG2-9416-330-96-TIP. (ZeroU на 16 А, три фазы, 400 В, 36 розеток IEC (30 x C13 и 6 x C19).
Естественно, все что будет изложено далее относится к любому оборудованию, которое «отзывается» по SNMP\MQTT\Modbus.
Сборщик — промышленный одноплатный компьютер Napi2 под управлением NapiLinux 0.3.1 с веб‑интерфейсом NapiConfig2, в котором многие параметры сборщика правится без ssh. В NapiConfig2 нужно «вписать» только часть конфига Telegraf для опроса датчиков (для каждого датчика конфиг свой) и есть возможность тестировать каждый датчик по отдельности, а также смотреть оперативные данные из базы данных InfluxDB.
Мы все действия производили на одноплатнике NAPI2 (RK3568,4Gb,32GB EMMC), но для решения задачи подойдет любой одноплатник с достаточным процессором и количеством памяти или даже виртуальная машина (докер).
Нам в данном случае был важно показать простоту настройки опроса на NapiLinux и NapiConfig. Мы делали сборки NapiLinux для нескольких платформ (включая х86) вплоть до вервсии 0.2.7, где есть вся описанная функциональность. Более старшие версии NapiLinux мы пока собираем только для платформ на NapiLinux и при накоплении фич, соберем для остальных платформ, так как это требует значительных ресурсов и времени.

Лирическое отступление. Конечно, связку «Telegraf — Influx — Grafana» можно поставить на виртуалке или в докере. Мы это делаем, и у нас даже есть готовый докер. Но нужно связать Telegraf и Influx, сделать «бакет» в Influx, связать Grafana сInflux, в правильное место не забыть положить MIB‑файлы при SNMP опросах.
Это все делается, но требует заметного времени для настройки (особенно, если этим не заниматься постоянно). Процесс отладки опроса датчика будет как отдельная «песня», и в докере сделать тоже можно, но не слишком удобно. Делая мониторинг «и так, и сяк», я выбрал для быстроты удобства свой тул NapiConfig.
Тянет ли задачу одноплатник с ресурсами уровня Rockchip RK3568?
Одноплатник Napi2 построен на Rockchip RK3568, здесь четыре ядра Cortex‑A55, 4 ГБ памяти, eMMC на борту, два гигабитных порта.

Состояние системы после почти двух суток непрерывной работы:
=== HW === NNZ Napi 2 4 6.18.31-g87470cd15657 === MEM === total used free shared buff/cache available Mem: 3897 1605 1871 215 806 2292 Swap: 0 0 0 === LOAD === 0.00 0.01 0.00 1/279 15727 12:27:08 up 1 day, 20:05, 3 users, load average: 0.00, 0.01, 0.00
Load average стоит на нулях по всем трем окнам усреднения. Из 3897 МБ памяти занято 1605 МБ, swap не задействован ни разу за все время работы.
Сам стек мониторинга занимает вот столько:
influxd cpu 0.7% rss 156.4 MB grafana-server cpu 0.5% rss 125.4 MB telegraf cpu 0.9% rss 118.8 MB ИТОГО cpu 2.1% rss 400.6 MB
Сборщик, база и визуализация вместе дают 400 МБ резидентной памяти и два процента загрузки одного ядра из четырех. Это десятая часть установленной памяти, остальные три с половиной гигабайта на такой нагрузке не востребованы.
Объем базы на диске:
2.0K /var/lib/influxdb 5.1M /root/.influxdbv2 1.4M /var/lib/grafana
Пять мегабайт накопленных рядов по трем устройствам — вводы, фазы, порты, напряжение, ток, частота, мощность. InfluxDB жмет временные ряды плотно, и опасения про «мониторинг съест диск» к такой нагрузке отношения не имеют. Узкое место в такой задаче — в дисковой записи, а не в процессоре и памяти, но при подобном объеме ни SD, ни eMMC его «не замечают».
Практический смысл кейса сводится к тому, что оперативный мониторинг оборудования перестает требовать заявки на виртуалку, согласования сетевого доступа и доступа к облачному провайдеру. Инженер ставит железку в любое место, где есть связность по сети и получает сразу инструмент мониторинга и анализа.
Локальный контур: настройка и анализ в браузере
Опрос, хранение и отрисовка графиков происходят в пределах одного устройства внутри периметра ЛВС (LAN). Данные наружу не уходят, что важно с точки зрения информационной безопасности (ИБ), которая на предприятиях обычно запрещает чужие облака.
Настройка не требует консоли и знания того, где в NapiLinux лежит /etc/telegraf/telegraf.d. Работают два равноправных сценария:
сесть за сам Napi2 с монитором и клавиатурой,
открыть http://192.168.16.102/ с рабочего места по сети.
Второй сценарий — основной. Инженер правит конфигурацию датчика в браузере, тут же жмет «Тест», смотрит, что реально приходит в базу, сохраняет, и в соседней вкладке открывает Grafana на том же адресе с портом 3000.
Правка конфигурации и проверка результата живут в двух вкладках одного окна. На стенде с тремя устройствами это просто удобно, на пуле стоек с двадцатью устройствами типа POWERGuard позволяет спокойно работать, а не мучиться.
Структура прохождения данных

Состав NapiLinux и подготовка опроса. Устанавливать ничего не пришлось. Telegraf 1.28.2, InfluxDB и Grafana входят в состав системы и не «докатываются» пакетным менеджером с внешнего репозитория, что на закрытом объекте будет отдельной проблемой. NapiConfig2 дает к ним веб‑интерфейс.
Загрузка MIB через веб‑интерфейс
MIB — это база управляющей информации, описание объектов, которые устройство отдает по SNMP. Без MIB в конфигурации нужно писать.1.3.6.1.4.1.xxxxx.1.2.3.4, с MIB — EXAGATE‑GLOBAL‑REG::circuitsTable. Чтобы конфиг читался и Telegraf корректно опрашивал по SNMP обязательно необходимо иметь валидные MIB‑файлы.

У Exagate файлов два. Глобальный ExagateMIB‑Global.mib с общим деревом производителя и PWG2_MIB.mib под конкретную серию. Оба лежат в открытом доступе на странице устройства у дистрибьютора, архив pwg2_mib.zip на вкладке «Файлы».
В NapiConfig2 за это отвечает раздел «Сервисы, SNMP, MIBs». Загруженные пользователем файлы помечаются как «Загруженный», остальные как «Системный». Системные входят в состав net‑snmp и лежат в /usr/share/snmp/mibs, там же RFC-1215, SNMPv2-TC, IP‑FORWARD‑MIB, IPV6-ICMP‑MIB и прочая база. Пользовательский файл кладется в тот же каталог, поэтому в конфигурации датчика строка path закомментирована, каталог по умолчанию уже тот, что нужен.
Про важные грабли. MIB импортируют друг друга. Если загрузить только PWG2_MIB.mib и забыть глобальный, резолвинг развалится, Telegraf выдаст ошибку про несуществующий модуль и опрос не стартует вообще. Комплект необходимо загружать целиком.

Датчик как единица конфигурации Telegraf
В NapiConfig2 источник данных называется «датчиком» и представляет собой фрагмент конфигурации Telegraf со своим жизненным циклом. Список лежит в разделе «Сервисы, Датчики». У каждой записи статус «Активен или Неактивен», производитель, описание, метки. Служба целиком останавливается, перезапускается и чистит свою БД с того же экрана.

Конфигурация правится в браузере с подсветкой синтаксиса. Рабочий вариант для Exagate, сокращенный до трех таблиц выглядит так (и ниже рахбор листинга подробнее):
[[inputs.snmp]] agents = ["udp://<IP>:161"] version = 2 community = "public" #path = ["/usr/share/snmp/mibs"] [[inputs.snmp.field]] oid = "RFC1213-MIB::sysUpTime.0" name = "uptime" [[inputs.snmp.field]] oid = "EXAGATE-GLOBAL-REG::systemName.1" name = "name" is_tag = true [[inputs.snmp.table]] oid = "EXAGATE-GLOBAL-REG::circuitsTable" name = "PWG-9332-307-91-SIPH" inherit_tags = ["name"] index_as_tag = true [[inputs.snmp.table]] oid = "EXAGATE-GLOBAL-REG::phasesTable" name = "PWG-9332-307-91-SIPH" inherit_tags = ["name"] index_as_tag = true [[inputs.snmp.table]] oid = "EXAGATE-GLOBAL-REG::portsTable" name = "PWG-9332-307-91-SIPH" inherit_tags = ["name"] index_as_tag = true
agents — адрес и порт датчика. SNMP работает поверх UDP, и потери на маршруте неотличимы от отказа агента, если не смотреть на счетчики ошибок отдельно. Забегая вперед, сначала думали именно на сеть.
version = 2 версия SNMP (Exagate также поддерживает безопасный SNMP3)
field и table. field снимает одиночный скаляр, у которого индекс либо нулевой (sysUpTime.0), либо указывает на конкретную строку (systemName.1), а table обходит таблицу целиком.
is_tag = true превращает имя устройства в тег, а inherit_tags прокидывает его в метрики таблиц. Без этого точки от трех разных PDU слились бы в одну серию, measurement у них одинаковый.
index_as_tag = true добавляет тег index с индексом строки таблицы.
name у таблицы задает имя measurement. Сюда зашита модель, PWG-9332-307-91-SIPH.

Проверка конфигурации в тестовом режиме
Веб‑интерфейс хранит файлы датчиков отдельно, что позволяет запускать Telegraf в тестовом режиме и показать оперативно три вещи — поток данных, лог и код возврата.
В потоке видно line protocol, ровно то, что уйдет в InfluxDB.
> PWG-9332-307-91-SIPH,agent_host=10.0.0.15,host=napi‑armoredpenguin,
name=PDU‑selectel-163 C4.Current=0i 1 785 416 549 000 000 000
Слева направо идут measurement, теги, поля, метка времени в наносекундах. В логе видна версия Telegraf, список загруженных плагинов и предупреждение о том, что в тестовом режиме выходы не используются. Последнее важно, в базу при нажатии кнопки ничего не пишется, кликать можно сколько угодно.
Ценность здесь в длине цикла правки. Изменил OID, нажал «Тест», увидел строки. Удобнее и быстрее, иначе — поправил конфигурацию, перезапустил службу, полез в лог.

Постобработка таблиц вида «имя‑значение» с помощью Starlark
«Из коробки» красивых метрик добиться не получалось. В нормально спроектированном MIB каждая колонка таблицы это отдельный объект со своим OID и именем, а строка адресуется индексом. Telegraf такой случай разбирает сам, колонки становятся полями, индекс уходит в тег.
У вендора Exagate таблицы устроены иначе. Есть колонка circuitName с текстовым названием измерения и колонка circuitValue с числом. То же самое в phasesTable (phaseName и phaseValue) и в portsTable (portName и portValue). Логика вендора понятна. Один формат подходит для любой комплектации, набор строк меняется прошивкой, MIB при этом трогать не надо.
Для базы временных рядов такая форма неудобна. В InfluxDB приезжают точки, у которых поле circuitValue равно нулю, а что именно измерено, лежит в соседнем строковом поле. Значение обезличено. В Grafana нельзя просто выбрать поле C4.Current, придется на каждой панели фильтровать по строковому полю, а в InfluxDB индексируются теги, поля не индексируются. На суточном объеме точек выборка становится заметно медленной.

Лечится это на этапе сбора данных и постобработки данных «на лету». Имя перекладывается из значения поля в имя поля, пока метрика еще внутри Telegraf. Для такой работы есть прекрасный инструмент — processors.starlark, встроенный интерпретатор одноименного диалекта Python. Инструмент универсален и очень мощный, поскольку дает почти полноценный Python прямо в конвейере сбора, без внешних скриптов и без крона.
Скрипт пост обработки метрик для случая с PDU‑устройством Exagate
[[processors.starlark]] namepass = ["PWG-9332-307-91-SIPH"] source = ''' PAIRS = [ ("circuitName", "circuitValue"), ("phaseName", "phaseValue"), ("portName", "portValue"), ] def apply(metric): for name_field, value_field in PAIRS: label = metric.fields.get(name_field) if label == None: continue value = metric.fields.get(value_field) if value == None: return None metric.fields.clear() metric.fields[label.strip().replace(" ", "-")] = value return metric '''
Для метрик нужного устройства берется число из circuitValue и строка из circuitName, пробелы в строке меняются на дефис, старые поля выбрасываются, число записывается единственным полем с осмысленным именем. Безымянный circuitValue превращается в C4.Current, C6.Fuse, C6.Load. Замена пробелов нужна потому, что часть имен устройство отдает с пробелами, а поле с пробелом в имени неудобно доставать в базу данных.
Деградация SNMP‑агента при непрерывном опросе с Grafana как инструмента диагностики
Опрос гоняли с коротким интервалом несколько суток подряд, снимая все доступные таблицы целиком. Штатный сценарий эксплуатации у такого оборудования более мягкий, система мониторинга дергает PDU раз в несколько минут и получает десяток значений. Интересовало поведение под непрерывной нагрузкой.
Про обнаружение пропусков на коротком масштабе:
Прелесть Grafana в том, что при анализе графика можно выделить любой промежуток для анализа. От секунд то месяцев. Притом «окно» анализа может быть произвольным.
Данные поступают равномерно — раз в в 10 секунд.

В результате рассмотрения различных «окон» обнаруживаем пропуски

На пятиминутном окне видно три измерения там, где должно быть около 30 измерений. При этом ни Telegraf, ни PDU не ругались заметным образом. В логе изредка мелькали таймауты, счетчики ошибок росли медленно, устройство отвечало на веб‑интерфейс, sysUpTime шел вперед без сбросов. В такой ситуации систему мониторинга принято считать исправной, поскольку данные формально идут.
Существенная деталь состоит в масштабе. Разжать то же окно до суток и включить в панели интерполяцию достаточно, чтобы Grafana нарисовала непрерывную линию, соединив соседние точки. График будет выглядеть безупречно. Пропуски такого рода могут жать в системах мониторинга годами.
Увидеть их удалось только при масштабе в минуты и отрисовке точками.
Корреляция между двумя PDU‑устройствами при испытаниях
Следующий шаг испытаний состоял в том, чтобы развернуть то же самое на сутки по каждому из двух PDU.


Совпадение по времени дало объяснение. Ровно в тот момент, когда один PDU начал опрашиваться ровно, второй начал терять запросы. Вот тут уже время привлекать вендора — проблема есть и четко идентифицируется. Сразу скажем, что вендор причину нашел и исправил — одинаковые MAC адреса на двух устройствах давали такой неприятный эффект.
Отмечу, что просто из логов такая картина не собирается, тем более невозможно найти связь двух устройств‑ из потока однотипных строк про таймауты, невозможно связать событие на одном устройстве с событием на другом. А вот две панели рядом на одном дашборде позволяют четко увидеть картину происходящего.
Параметры Telegraf, влияющие на укладку в интервал
Если по нащему примеру будете заниматься опросами с целью «ловли» багов оборудования, полезно знать параметры Telegraf. Они доступны через SSH в файле.

interval задается прямо в секции плагина, глобальный agent.interval при этом трогать не надо. Разные устройства спокойно живут с разной частотой в одном Telegraf.
timeout и retries, по умолчанию 5 секунд и 3 попытки. Если агент не успевает, Telegraf пишет в лог did not complete within its interval, следующий цикл наезжает на предыдущий, растет буфер, потом начинаются дропы.
max_repetitions — число строк, запрашиваемых одним GETBULK, по умолчанию 50. Для слабого контроллера это тяжелый запрос, ответ не влезает в MTU и фрагментируется на пути. Снижение до 10–25 строк снимает часть таймаутов ценой лишних round‑trip.
Состояние мониторинга после исправлений MAC‑адресов


Отдельным пунктом стоит отметить, что точки измерений, соединенные линиями очень удобны и наглядны, но могут быть недостоверны — Grafana при пропущенных данных соединит две точки в «красивый график». Особенно это опасно при нулевых значениях (например, пока нет нагрузки, прибор выдает значение тока «ноль»). Если посмотреть на нижние графики, — там так и есть, — и непонятно сколько сделано измерений. Поэтому вид графика надо выбирать «от задачи».
Если прибор точно исправен и проверен, то график с линиями более удобный, если надо проверить равномерность ответов — отдельные точки «самое то». Особенно полезны точки на одном уровне (даже на уровне ноль), где главное — факт ответа устройства.

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

За двое суток на графике читается суточный ход в диапазоне от 216 до 225 В. Провал приходится на рабочие часы, максимум на предутренние. Это типичное поведение городской питающей сети там, где нет своей подстанции. Частота при этом стоит как вкопанная, 49.96 Гц с разбросом в сотые доли.

Заглянем«под капот» вот этого графика:

Примеры дашбордов в формате json, которые можно импортировать в нашем репозитории https://github.com/lab240/telegraf‑grafana‑configs. Там же вы найдете конфиги Telegraf для датчиков Modbus, Snmp, Mqtt
Особенность Grafana в том, что это мощнейший конструктор. Можно строить свои «дашборды» с теми данными, которые нужны вам и в том представлении, которое наиболее оптимально. Можно разбивать на несколько дашбордов, чтобы не утяжелять экран. И, самое интересное, можно собирать на один дашборд данные с разных устройств — и не важно, один это вендор или разные.
Да, сделать новый дашборд довольно непросто, потому что надо написать запрос на языке Flux, но имея шаблон и ИИ как помощника — задача становится решаемой.

Еще одна полезная функциональность Grafana — переменные, которые можно выбирать и все дашборды поставят выбранную переменную в запрос. Наш дашборд построен на трех переменных — measurement, host и device. Панели разделены на вводы © и линии (L), плюс сводные gauge по напряжению, току, частоте и активной мощности.
Добавление нового PDU в стойку не требует ни новой панели, ни правки запросов, достаточно нового датчика в NapiConfig2, дальше устройство появляется в выпадающем списке device.
Выводы по кейсу мониторинга устройств
Одноплатника на Linux достаточно для сбора и анализа данных. Компьютер уровня Napi2 с NapiLinux тянет весь стек мониторинга без внешнего сервера. Ограничение лежит в дисковой записи, для стойки ее хватает с запасом.
Данные не покидают периметр ЛВС организации. Настройка и анализ делаются в браузере, на самом устройстве либо с рабочего места по сети.
Софт уже весь в системе. Telegraf, InfluxDB и Grafana входят в состав NapiLinux, NapiConfig2 дает к ним веб‑интерфейс. MIB грузится через браузер, конфигурация датчика правится там же и проверяется кнопкой Тест без записи в базу.
Starlark — мощный и несколько недооцененный инструмент. Он закрывает разбор нестандартных таблиц десятком строк на этапе сбора. Иначе та же работа размазывается по всем панелям дашборда в виде фильтров по строковым полям. Хардкодить в скрипт имена устройств не надо, для этого есть namepass.
Grafana работает как измерительный инструмент. Пропуски опроса нашлись по графику, а связь между двумя устройствами стала видна только потому, что панели стояли рядом. Смотреть надо на крупном масштабе и точками, а на суточном окне с интерполяцией такая проблема не видна.
Тем же стендом можно искать неисправности. Суточный ход питающей сети, разрешение измерительного тракта, момент деградации агента выдает та же связка тулов.
Что планирую сделать еще
Перевести опрос на SNMP v3.
Погонять тесты на длинной серии одновременно опрашиваемых устройств и найти потолок одного сборщика.
Спасибо всем, кто дочитал этот длинный труд до конца.
Надеюсь эта статья была полезна, по вопросам Napi, NapiLinux, NapiConfig вы можете обратиться по почте или чат в тг‑канале @napiworld. Всем удачи на ваших проектах.