Первый выпуск для каталога 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в строгом режиме