ELK Stack: централизованный анализ логов без платного Splunk
Разворачиваем Elasticsearch + Logstash + Kibana на продакшн-среде: как ELK даёт оперативную картину событий без лицензионных затрат на Splunk.
ELK Stack (Elasticsearch + Logstash + Kibana) активно продвигается сообществом в 2013-2014 как open-source альтернатива Splunk
Долгое время на вопрос «где смотреть логи» у нас был честный ответ: ssh на нужный сервер, tail, grep. Для парка в несколько машин это терпимо. Когда серверов становится больше двух десятков, такой подход превращается в квест - особенно когда инцидент захватывает несколько хостов одновременно и нужно сопоставить события по времени.
Splunk решает задачу хорошо, но его лицензионная политика больно бьёт по бюджету. На определённом объёме данных счёт становится значительным, а freemium-лимит в 500 МБ в день кончается быстро на активных серверах. Поэтому когда сообщество начало активно говорить про ELK - Elasticsearch, Logstash и Kibana - мы решили потрогать руками.
Что из себя представляет стек
Три компонента, каждый делает своё:
- Logstash - агрегатор и парсер. Принимает логи по разным протоколам (syslog, файлы, lumberjack), разбирает их через grok-паттерны и отправляет дальше.
- Elasticsearch - хранилище и поисковый движок. Индексирует всё что прислал Logstash, отвечает на запросы.
- Kibana - веб-интерфейс поверх Elasticsearch. Дашборды, фильтрация, визуализации.
Стек появился не вчера: Elasticsearch существует с 2010 года, Logstash примерно тогда же, Kibana - чуть позже. Но именно в 2013 году их начали активно продвигать как связку, и сообщество подхватило.
Как мы разворачивали
Начали с одного из клиентов на сопровождении - средний по размеру парк, примерно два десятка серверов, микс из веб-серверов, баз данных и служебных машин. Логи шли в rsyslog на каждом хосте, центральная агрегация отсутствовала.
Выделили отдельную виртуалку под ELK - Elasticsearch любит память, ему отдали 8 ГБ, сам стек развернули на CentOS 6. Elasticsearch на момент развёртывания - версия 1.0 RC, Logstash 1.3, Kibana 3 (последняя на тот момент).
Схема получилась простая:
серверы -> rsyslog -> Logstash (5514/udp) -> Elasticsearch -> Kibana
На каждом сервере настроили пересылку через rsyslog в Logstash. Logstash принимает syslog-поток, разбирает его grok-паттернами и кладёт в Elasticsearch с нужными полями: hostname, severity, facility, message, timestamp.
Самая трудозатратная часть - написать grok-паттерны для прикладных логов. Стандартный syslog разбирается из коробки, а вот nginx access log, PHP-ошибки или кастомные форматы приходится описывать руками. Grok - это, по сути, именованные регулярные выражения, и отлаживать их без инструментов неудобно. Нашли онлайн-дебаггер, стало проще.
Kibana-дашборды: в чём ценность
Раньше «посмотреть что происходит на серверах» означало зайти на несколько машин по очереди. Теперь открываешь Kibana и видишь:
- Общий поток событий - временная шкала с количеством сообщений. Аномальный всплеск ошибок виден сразу как пик на графике.
- Фильтрация по хосту или сервису - можно мгновенно срезать только нужный сервер или только nginx.
- Поиск по тексту - Elasticsearch полнотекстовый, искать «connection refused» по всем логам за последний час - одна строка запроса.
- Сопоставление событий по времени - когда инцидент затрагивает несколько хостов, видишь в одном окне что произошло на web01 в 14:32:15 и что в тот же момент делал db01.
Последний пункт - это именно то, чего не хватало при работе с отдельными машинами. Временная корреляция руками через несколько ssh-сессий - занятие для терпеливых.
Где споткнулись
Elasticsearch болезненно реагирует на нехватку памяти - при недостатке heap начинает swap, производительность падает кратно. На первой итерации выделили 4 ГБ, через неделю увидели проблему и удвоили. JVM-куча - половина от доступной памяти, это правило надо соблюдать.
Grok-паттерны для части логов так и не дописали до конца - часть приложений пишет в нестандартных форматах, и они попадают в Elasticsearch как неразобранный текст. Искать по ним можно, но структурированной аналитики нет. Задача висит в бэклоге.
Ещё один момент - ротация индексов. Elasticsearch хранит всё в индексах, и без настройки очистки старых индексов диск заканчивается. Настроили cron на удаление индексов старше двух недель - работает, но хотелось бы более элегантного решения.
Ansible-плейбуки для разворота стека мы активно используем - ELK не исключение, установка и базовая конфигурация автоматизированы.
Первые выводы
ELK работает. Не без шероховатостей, но задачу централизованного анализа логов закрывает - особенно по сравнению с «нет ничего». Kibana-дашборды дают оперативную картину без Splunk и его ценника.
Главное что изменилось в работе: теперь при инциденте первое действие - открыть Kibana, а не раскидывать руки по терминалам. Это экономит время и нервы.
Стек молодой - Elasticsearch 1.0 ещё официально не вышел на момент нашего развёртывания. Некоторые API ведут себя неожиданно, документация местами отстаёт от кода. Но сообщество активное, Issues на GitHub разбираются, и в целом ощущение что продукт двигается в нужную сторону.
На следующем клиенте планируем попробовать Logstash Forwarder - облегчённый агент для отправки логов вместо rsyslog-пересылки. Интересно, даст ли это что-то ощутимое по надёжности доставки.