ADG Оставить заявку
Блог Данные и аналитика 4 мин чтения

Kibana не звонит: написали скрипт алертинга поверх Elasticsearch своими руками

Kibana 3 умеет только показывать. Чтобы получать письма при всплеске ошибок, написали простой Python-скрипт с опросом Elasticsearch раз в минуту.

Контекст момента

Отсутствие встроенного алертинга в Kibana/Elasticsearch стимулирует разработку внешних решений

Когда мы разворачивали ELK в продакшне летом, у нас был один открытый вопрос: Kibana 3 красиво показывает логи, но уведомлений не отправляет. Тогда мы оставили это на Zabbix - он смотрит за числовыми метриками и при проблемах будит дежурного. Но у Zabbix есть слепое пятно: он не знает, что творится внутри лог-потока. Количество ERROR-записей в Elasticsearch - не его дело.

Прошло четыре месяца, и это слепое пятно начало нас беспокоить всерьёз.

Откуда взялась задача

У одного из клиентов - Java-приложение с внешними интеграциями. Интеграции периодически падают молча: HTTP 500 снаружи, стектрейс внутри лога, но сервис в целом работает, метрики по CPU/памяти нормальные, Zabbix молчит. Дежурный узнавал о проблеме от клиента заказчика, а не от инструментов - что примерно вдвое хуже по любой метрике.

Kibana на дашборде это всё прекрасно видит: есть виджет с количеством ERROR за последние N минут, есть временна`я шкала. Но смотреть на дашборд в три ночи никто не будет.

Значит, нужен что-то, что опрашивает Elasticsearch и само присылает письмо когда плохо.

Что смотрели, что не нашли

Поискали готовые решения. На GitHub нашлось несколько проектов в разной степени заброшенности - ни один не тянул на production-ready. Kibana 3 плагины смотрели - алертинг там не предусмотрен архитектурно, это фронтенд без серверной логики. Elasticsearch сам по себе тоже не отправляет уведомлений - это поисковый движок, не система мониторинга.

В итоге решили написать свой скрипт. Задача маленькая, требования простые - не надо строить систему, надо закрыть дыру.

Скрипт: минута, запрос, письмо

Python, минимум зависимостей - только requests для HTTP и стандартная библиотека для отправки почты. Логика прямолинейная:

cron раз в минуту -> скрипт -> запрос к Elasticsearch -> 
  если count > порог -> sendmail

Запрос к Elasticsearch - обычный count-запрос с временным фильтром «последние 5 минут» и фильтром поlog_level: ERROR. Elasticsearch HTTP API отвечает JSON с полемcount` - дальше сравниваем с порогом и решаем отправлять или нет.

Несколько вещей которые пришлось продумать сразу:

Подавление повторов. Если ошибки идут поток, не надо слать письмо каждую минуту. Сделали состояние: файл с временно`й меткой последней отправки. Следующее письмо - не раньше чем через 15 минут, даже если порог всё ещё превышен.

Разные пороги для разных индексов. У клиента несколько приложений, каждое пишет в свой индекс. Конфиг сделали в виде простого JSON-файла: список проверок, у каждой - паттерн индекса, поле уровня, порог, получатели.

Формат письма. Первая версия слала просто число: «Ошибок: 47». Оказалось бесполезно - непонятно какое приложение, что за ошибки. Доработали: добавили в письмо несколько примеров из той же выборки, первые три сообщения из ERROR-документов за тот же период. Это дало контекст без необходимости идти в Kibana для понимания масштаба.

Тайм-ауты. Elasticsearch иногда думает дольше обычного, особенно если индекс большой и запрос чуть сложнее. Поставили тайм-аут запроса 10 секунд и явный выход по коду ошибки - чтобы зависший cron-запрос не накапливался.

Как выглядит в работе

Скрипт крутится на том же хосте, где Logstash и Kibana - там же, в рамках управляемой инфраструктуры. Cron-запись простая, запуск от отдельного системного пользователя без лишних прав.

За первую неделю поймали два реальных инцидента раньше, чем о них сообщили. Один - именно та ситуация с падением интеграции, ради которой всё затевалось. Другой - неожиданный: ночная задача по генерации отчётов начала сыпать ClassNotFoundException из-за обновления библиотеки, которое разработчики выкатили без предупреждения. Без алертинга это обнаружили бы утром.

Что это такое и чем не является

Называть это «системой алертинга» неловко - это скрипт на 150 строк с cron-ом. Он не умеет эскалаций, не умеет дежурных расписаний, не умеет групп получателей с ack-ом. Для этого есть Zabbix и PagerDuty.

Но для задачи «сообщить команде что в логах что-то идёт не так» - справляется. Порог настраивается под каждое приложение, повторы подавляются, письма информативные. На текущем масштабе - достаточно.

Ограничение другое: скрипт проверяет только то, что мы явно описали в конфигурационном файле. Если появляется новое приложение - нужно добавить запись руками. Нет никакой автоматической детекции аномалий, нет machine learning, нет вероятностных порогов. Просто count > N.

Мы это принимаем. Инструмент сделан за два дня, закрывает конкретную дыру и не претендует на большее. Если задача вырастет - будем смотреть что к тому моменту появится из нормальных инструментов. Пока - вот этот скрипт, и он работает.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.