Skip to content

1.3.0 — SNMP, Loki и выход в каталог Arduino

Latest

Choose a tag to compare

@240974a 240974a released this 08 Sep 21:57

Первый выпуск для каталога Arduino: библиотека подаётся в реестр и ставится
через Менеджер библиотек, а не выкачиванием с GitHub.

Журнал научился уходить туда, где его читают не глазами: в систему мониторинга
и в хранилище логов. Оба приёмника были обещаны в 1.2.0 — теперь они есть.

Telnet отдаёт то же, что порт, и с цветом

Раньше в telnet уходил только текст сообщения: ни времени, ни уровня, ни
источника — по такому журналу нельзя было понять, когда что случилось и откуда.
Теперь строка та же, что в порту, и раскрашена так же: терминал понимает те же
последовательности ANSI.

Включать ничего не нужно. Убрать цвет, если журнал разбирают скриптом, —
color::setEnabled(false); настройка общая для порта и telnet.

Для этого FmtColor научился писать в любой Print, а не только в Serial:
color::write(поток, запись). Из неё же собран и прежний serialSink.

Обошлось в двенадцать байт: таблицы цветов в прошивке уже были.

Уведомления по SNMP

FmtSnmp.h шлёт монитору то, что требует вмешательства, — err и выше:

snmp::begin(IPAddress(192, 168, 1, 10));
snmp::setEnterpriseOid("1.3.6.1.4.1.12345");
log::addSink(snmp::sink);

Уходит trap SNMPv2c на порт 162 — туда, где его ждёт Zabbix, PRTG или Nagios.
В trap идут текст сообщения, номер уровня и имя источника: по двум последним
фильтруют, не разбирая текст.

Пакет собирается своим кодом, без библиотеки SNMP: trap — единственное, что
нужно журналу, и его кодирование занимает меньше места, чем любая готовая
реализация вместе с разбором запросов, которые плате слушать незачем.

Строки для Loki

FmtLoki.h складывает строки в Loki — их ищут по меткам в той же Grafana, что
и метрики Prometheus:

loki::begin("192.168.1.10");
loki::addLabel("job", "boiler");
log::addSink(loki::sink);

level и source библиотека ставит метками сама, остальные задаёте вы. Строки
уходят пачками — по шестнадцать или раз в пять секунд, что случится раньше;
loki::flush() досылает их перед перезагрузкой.

Поднять Loki с Grafana можно одной командой: в extras/loki лежит готовый
контейнер, источник данных в нём уже прописан. Там же — что делать, если
строки не появляются.

Оба приёмника не задерживают loop()

sink() вызывается изнутри log::err(), поэтому он только запоминает строку,
а по сети её отправляет handle(). Что не поместилось, пока сеть недоступна,
теряется предсказуемо — самое старое, и это видно в lost().

Замеры пересняты

Прежние числа сравнивали прошивку с журналом и прошивку совсем без сети,
поэтому в цену приёмника попадал весь сетевой стек. Теперь мерится то, что
добавляет сам модуль:

было стало
журнал с выводом в порт +2024 Б +236 Б
цветной вывод +436 Б +12 Б
telnet с историей +10 696 Б +2296 Б
журнал на веб-странице +14 216 Б +4268 Б

Новые приёмники: SNMP +564 Б, Loki +2560 Б. SNMP дёшев, потому что шлёт
UDP-пакет; Loki открывает HTTP-соединение; telnet и веб-страница поднимают на
плате сервер — он и составляет их цену.

Веб-страница выглядит как панель управления

Раньше это была ровная полоса из полей и кнопок, где нужное искали
перечитыванием. Теперь элементы собраны в группы — плата, фильтр, время,
журнал, — с подписями и разделителями между ними; глаз находит нужное по
месту. Связь с платой показывает точка рядом со словом: зелёная — строки
идут, жёлтая — связь оборвалась и восстанавливается.

Подписи и подсказки переведены на русский.

Светлая тема

Кнопка со солнцем и луной в правом углу переключает тему; выбор запоминается,
а при первом открытии берётся системный — у кого светлая система, тот и
страницу увидит светлой.

Цвета уровней подобраны отдельно для каждой темы и проверены на контраст: все
проходят порог читаемости WCAG. Заодно поднят контраст отметки времени на
тёмной теме — она была чуть ниже порога.

Журнал не теряется при перезагрузке страницы

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

Строки, которые плата отдаёт заново при подключении, не удваивают журнал:
повторы отсеиваются. Кнопка «очистить» теперь спрашивает подтверждение —
она убирает и сохранённое, а вернуть его будет неоткуда.

Веб-страницу стало можно читать

Раньше каждая новая строка утаскивала страницу вниз, и прочитать что-то в
середине журнала не получалось. Теперь стоит перемотать выше — и страница
замирает на прочитанном месте: новые строки копятся, не двигая текст, даже
когда старые вытесняются из буфера. Вернуться к свежему можно кнопкой «Читать
последнее», на ней же видно, сколько строк пришло, пока вы читали.

Пауза останавливает поток, чтобы прочитать текущий вид не спеша, без
перемоток.

Вместо выбора даты — скольжение по времени: − и + с выбором шага —
минута, десять минут, час, полсуток, сутки. Календарь показывал начало дня, а
нужное место всё равно искали прокруткой; шаг доводит до него сразу. Шаг запоминается между
открытиями страницы, а шагают кнопки от собственной цели, а не от того, что
видно на экране, — иначе промах копился бы с каждым нажатием.

Плату выбирают из списка

Адреса, к которым подключались, остаются в списке у поля: к соседней плате
переключаются выбором, а не набором заново. Ненужный убирает кнопка рядом —
вместе с адресом забывается и сохранённый от него журнал, чтобы не занимал
место.

Свежий адрес встаёт первым: к последней плате возвращаются чаще всего.

Адрес платы можно передать ссылкой

extras/log.html?host=192.168.1.50 открывает журнал сразу нужной платы.
Удобно, когда их несколько: на каждую заводится своя закладка. Указанный в
ссылке адрес главнее запомненного.

Что проверено

  • 107 тестов на машине разработчика, плата не нужна: pio test -e native
  • пакет SNMP разобран сторонней библиотекой pyasn1 — метки, длины и OID
    оказались верны не только по нашим меркам
  • тело запроса отправлено в настоящий Loki: строки вернулись обратно с целыми
    метками, кавычками и кириллицей
  • сборка на шести платформах, семь примеров, arduino-lint в строгом режиме