У меня уже была куча метрик. Prometheus собирает железо, Grafana рисует историю, Netdata ловит «здесь и сейчас». Отдельный скрипт каждый час смотрит nginx-лог и пишет мне в телефон, если пришёл новый посетитель. Данные есть.
Проблема в другом: я читаю эти данные, только когда что-то сломалось. Дашборды висят, логи пишутся, а раз в неделю я заглядываю в Grafana, вижу уже случившийся инцидент и разбираюсь постфактум. Мониторинг есть, а внимания к нему — нет.
Захотелось, чтобы не я шёл к метрикам, а метрики приходили ко мне словами: короткий отчёт раз в сутки о том, что произошло, что сломалось и что подозрительно.
Что на входе
Ничего нового собирать не пришлось — всё уже лежало в системе:
- Loki — структурированный nginx-лог (запросы, статусы, пути, IP),
лог мониторинга посетителей, лог бэкапов;
- Prometheus / Netdata — железо: CPU, память, диск, uptime;
- приложение уже живёт в той же Docker-сети, что Loki и Prometheus, так что
достаёт метрики запросами по HTTP без всяких прокси.
Данные за сутки собираются в один компактный JSON: трафик, доля 4xx/5xx, топ страниц, топ IP и User-Agent, число новых посетителей, попадания сканеров, состояние бэкапа, ресурсы сервера.
Что на выходе
Один Markdown с тремя разделами: Новости, Проблемы, Риски. Без воды: факты из данных, короткие пункты, а на проблему — предлагаемое действие. Если в данных чего-то нет, модель не должна это выдумывать.
Например, первый же реальный отчёт написал: доля ошибок за сутки около 27%, диск занят почти на 90%, CPU под 65% — и предложил разобраться с ошибками и расширить диск. Я это увидел утром в телефоне, а не тогда, когда диск кончится.
Как это устроено
Для модели используется тот же YandexGPT, что и в авто-тегировании статей (yandexgpt-lite, дешёвый). Я вынес общий хелпер complete(system, user), чтобы не дублировать код: теги и дайджест ходят в один и тот же шлюз.
Дальше — просто:
- результат кэшируется по дате (
ai-digest.json), чтобы не платить
за генерацию на каждый запрос;
- есть API:
GET /api/ai/digestотдаёт сегодняшний отчёт, админский
POST /api/ai/digest/refresh — перегенерировать;
- если LLM недоступен — работает резервный режим: отчёт собирается
правилами из тех же метрик. Без ИИ, но не пусто.
Ежедневно в 7:00 UTC cron дергает генерацию и отправляет результат в отдельный топик ntfy digest. Так отчёт приходит на телефон как и алерты Grafana, только это не тревога, а сводка.
Круглая иконка, которая дрейфует
Захотелось ещё и «ручной» вход в отчёт прямо с сайта. Сделал круглую ИИ-иконку: она закреплена справа снизу, отделена от основного фрейма сайта и слегка смещается при прокрутке (параллакс на requestAnimationFrame). Кликаешь — выезжает панель с дайджестом, заголовком и источником: LLM или резервный режим.
Это сознательно не встроенный виджет в потоке страницы, а отдельный плавающий объект — как ассистент, который всегда под рукой, но не мешает читать.
Чему я научился
Метрики без интерпретации стареют. Данные, которые никто не читает, почти бесполезны. LLM здесь не заменяет мониторинг, а закрывает последнюю милю: превращает набор чисел в связный короткий текст, который можно прочитать за двадцать секунд.
Всегда нужен резервный режим. Модель может быть недоступна: кончились квоты, упал API, поменялся ключ. Отчёт на правилах хуже, но он есть — и это важнее, чем красивая формулировка.
ИИ советует, а не действует. Дайджест ничего не перезапускает и не чистит диск. Он приносит мне наблюдение и вопрос. Решение — всё ещё моё.
Теперь у песочницы есть голос. Осталось научиться его слушать до того, как сервер придёт говорить сам.
Загрузка…