Zabbix и ELK: не конкуренты, а разные инструменты для разных задач
Разбираем, почему Zabbix и ELK-стек не заменяют друг друга: метрики с порогами - это одно, а поиск по логам - совсем другое. Интегрируем алерты.
Рост популярности ELK-стека ставит вопрос о разграничении мониторинга метрик и агрегации логов
После того как мы перевели лог-инфраструктуру одного из клиентов на ELK, коллеги из нескольких других проектов начали задавать один и тот же вопрос: «Это теперь вместо Zabbix?». Вопрос звучит логично, но ответ - нет, и вот почему.
Zabbix и ELK решают фундаментально разные задачи. Путаница возникает потому, что оба инструмента «видят» состояние серверов - только смотрят на него с разных сторон. Мы потратили несколько недель, чтобы понять где граница, и в итоге оба стека работают рядом, дополняя друг друга.
Zabbix: пороги и реакция
Сильная сторона Zabbix - числовые метрики и алерты по порогам. CPU выше 80% пять минут подряд - сработает триггер, придёт уведомление. Диск заполнен на 90% - то же самое. Хост недоступен по ICMP - немедленно. Это задача класса «наблюдать за известными параметрами и орать когда плохо». Zabbix в этом дисциплинирован: auto-discovery с LLD закрывает добавление новых хостов без ручной возни с конфигами, шаблоны переиспользуются между клиентами.
Что Zabbix делает плохо - произвольный анализ текстовых логов. Есть item типа «log» и «logrt», можно следить за файлом и проверять содержимое регуляркой. Но это не тот инструмент для запроса «покажи мне все WARNING-записи из трёх сервисов за последние два часа с группировкой по хосту». Такой запрос у Zabbix просто не предусмотрен.
ELK: поиск, а не наблюдение
Elasticsearch с Logstash и Kibana - это про агрегацию и ad hoc поиск. Когда что-то уже сломалось или ведёт себя странно - ELK позволяет за минуты восстановить цепочку событий по всем хостам одновременно. Это инструмент расследования, а не дежурства.
Сам по себе Kibana 3 не умеет слать уведомления - это просто красивый дашборд поверх Elasticsearch. Нет триггеров, нет дежурных звонков, нет эскалаций. Kibana не позвонит дежурному в три ночи.
Так что расклад получается простым:
- Zabbix - дежурит, следит за порогами, будит при проблемах.
- ELK - хранит историю, отвечает на вопросы при разборе полётов.
Где всё-таки нужна интеграция
Вот тут начинается интересная часть. Инцидент, который заставил нас задуматься: Zabbix сработал по CPU на app01, дежурный пришёл разбираться - и первым делом открыл Kibana искать в логах что происходило в момент скачка. Два инструмента, два окна, ручная синхронизация по времени. Неудобно.
Хотелось следующего: когда Zabbix фиксирует проблему, соответствующее событие попадает в Elasticsearch - чтобы на дашборде логов было видно временну́ю метку алерта рядом с логами из того же периода. Корреляция без ручной работы.
Решили через action в Zabbix с Remote command: при срабатывании триггера запускается скрипт, который кладёт JSON-запись в Elasticsearch через его HTTP API.
Скрипт получает от Zabbix макросы: {HOST.NAME}, {TRIGGER.NAME}, {TRIGGER.SEVERITY}, {EVENT.DATE}, {EVENT.TIME} - и формирует документ примерно такой структуры:
{
"@timestamp": "2014-07-18T14:31:00Z",
"type": "zabbix_alert",
"host": "app01.prod",
"trigger": "CPU utilization > 80%",
"severity": "HIGH",
"status": "PROBLEM"
}
Отправляется через curl в Elasticsearch на /zabbix-alerts-2014.07/alert/ (свой индекс, чтобы не мешать с логами). При восстановлении триггера - второй документ с "status": "RESOLVED" и временем закрытия.
В Kibana добавили этот индекс в список источников и настроили визуализацию: на временной шкале логов теперь видны вертикальные метки алертов Zabbix. Когда смотришь на пик ошибок nginx - видишь, что за 30 секунд до него Zabbix зафиксировал проблему с памятью на соседнем хосте.
Несколько практических наблюдений
Индексы алертов держи отдельно. Мы сначала писали в общий индекс логов - стало тяжело фильтровать. Отдельный индекс zabbix-alerts-* и отдельный паттерн в Kibana - правильное решение.
Временны́е зоны - отдельная боль. Zabbix хранит время в UTC, но в макросах {EVENT.DATE} и {EVENT.TIME} отдаёт локальное время сервера Zabbix. Если Zabbix-сервер в Москве, а Elasticsearch принимает UTC - нужно конвертировать в скрипте. Потратили час пока разобрались откуда расхождение в три часа.
Severity-маппинг лучше делать явно. У Zabbix шесть уровней severity: Not classified, Information, Warning, Average, High, Disaster. В Elasticsearch мы маппим их в числовой severity_num от 0 до 5 - удобно для сортировки и фильтров в Kibana.
Zabbix не заменяет Kibana для алертов. Появлялась идея настроить alerting на стороне ELK - триггерить на «слишком много ERROR в логах за минуту». Kibana 3 этого не умеет, внешние инструменты пока не смотрели. Zabbix через log-items может следить за файлом, но при централизованном сборе логов на ELK-хост это означает дублирование пайплайна. Пока оставили как есть: ELK для анализа, Zabbix для алертов.
Где сейчас
Интеграция работает около двух недель на одном клиентском окружении. Схема оправдала ожидания - разбор инцидентов стал быстрее: временны́е метки алертов в Kibana сразу указывают на нужный период, не нужно вручную синхронизировать временны́е окна между инструментами.
Планируем распространить на остальных клиентов из управляемой инфраструктуры. Скрипт простой, на bash, параметры через переменные окружения из Zabbix-action - можно адаптировать под любой экземпляр Zabbix за полчаса.