Elastic Beats в продакшне: Filebeat и Metricbeat вместо logstash-forwarder
Заменили logstash-forwarder на Filebeat и Metricbeat на всех серверах - потребление памяти упало в четыре раза. Конфиги модулей, pipeline в Logstash, Kibana-дашборды.
Elastic Beats (Filebeat, Metricbeat, Packetbeat) как замена logstash-forwarder на продакшн-серверах в 2017 году
В январе мы переехали на Elastic Stack 5.x и там же впервые нормально поставили Filebeat. Тогда это был один клиент и тридцать хостов. К марту Beats развернуты на всех managed-проектах, и есть что рассказать про Metricbeat - инструмент, который мы несправедливо игнорировали несколько месяцев.
Почему ушли от logstash-forwarder
logstash-forwarder (бывший lumberjack) - это Go-агент для пересылки логов в Logstash. Работал, но с характером. Главная претензия - потребление памяти росло непредсказуемо, постепенно. На нагруженном хосте с несколькими активными лог-файлами он мог занимать 150-200 МБ, иногда больше. При этом Filebeat на той же машине уверенно держится в 30-50 МБ. Четырёхкратная разница - это не теория, это то, что мы видим в мониторинге.
Второй момент - registry. Filebeat хранит позицию в каждом файле в registry/filebeat, и при перезапуске продолжает с того места где остановился. logstash-forwarder терял позицию при некоторых сценариях ротации и перезапуска сервиса, что приводило к повторной отправке событий. На больших объёмах дубликаты в Elasticsearch начинают заметно раздражать.
Официально logstash-forwarder помечен как deprecated начиная с Elastic Stack 5.0. Elastic прямым текстом говорит: используйте Filebeat. Поводов тянуть не осталось.
Как выглядит конфигурация Filebeat
Конфиг минималистичный. Один YAML, секция filebeat.prospectors, каждый prospector - набор путей и метаданные:
filebeat.prospectors:
- input_type: log
paths:
- /var/log/nginx/access.log
- /var/log/nginx/error.log
fields:
service: nginx
env: production
fields_under_root: true
ignore_older: 24h
- input_type: log
paths:
- /var/log/app/*.log
fields:
service: app
env: production
fields_under_root: true
multiline:
pattern: '^\d{4}-\d{2}-\d{2}'
negate: true
match: after
output.logstash:
hosts: ["logstash.internal:5044"]
fields_under_root: true - важная опция. Без неё кастомные поля падают в подобъект fields, и в Kibana их нужно искать как fields.service. С этой опцией поля попадают на верхний уровень документа, что удобнее для фильтров и визуализаций.
ignore_older: 24h - тоже рекомендуем всегда ставить явно. Иначе при старте Filebeat добросовестно начнёт читать все логи с начала файла, и Logstash получит неожиданный всплеск.
Multiline для Java-стектрейсов или многострочных application-логов: negate: true, match: after означает «строки которые НЕ начинаются с паттерна - это продолжение предыдущего события». Работает корректно.
Logstash pipeline: что делаем с событиями
Входящий поток Beats принимает input на порту 5044:
input {
beats {
port => 5044
}
}
Дальше filter-секция. Для nginx-логов - grok по стандартному COMBINEDAPACHELOG, потом несколько enrichment-шагов:
filter {
if [service] == "nginx" {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}" }
}
geoip {
source => "clientip"
target => "geoip"
}
useragent {
source => "agent"
target => "ua"
}
mutate {
convert => { "response" => "integer" }
convert => { "bytes" => "integer" }
}
}
}
GeoIP и useragent - это то что Logstash умеет делать за вас без написания кода. GeoIP обогащает IP-адрес координатами и страной (нужна база GeoLite2, она бесплатная). useragent парсит строку User-Agent и вытаскивает браузер, OS, устройство в отдельные поля. Оба фильтра работают синхронно и ощутимо замедляют pipeline при высоком потоке - но на типичном веб-проекте это не критично.
Результат в Elasticsearch уходит через output с шаблоном индексов по сервису:
output {
elasticsearch {
hosts => ["elasticsearch.internal:9200"]
index => "logs-%{service}-%{+YYYY.MM.dd}"
template_name => "logs"
template_overwrite => false
}
}
Разбивка по сервису в имени индекса позволяет гибко управлять retention: для nginx-логов держим 30 дней, для app-логов - 90. Curator удаляет старые индексы по расписанию.
Metricbeat: про что мы раньше не думали
До этого системные метрики с хостов собирал Zabbix-агент и частично collectd. Metricbeat мы попробовали в рамках той же волны перехода на Beats.
Идея Metricbeat в том, что у него есть модули для разных сервисов: system, nginx, mysql, redis, apache, docker и другие. Включаешь модуль - и он автоматически собирает специфичные для этого сервиса метрики в заранее описанную схему. Не нужно вручную прописывать что собирать.
Конфиг для модуля system:
metricbeat.modules:
- module: system
metricsets:
- cpu
- memory
- network
- diskio
- filesystem
period: 30s
cpu_ticks: false
- module: nginx
metricsets: ["stubstatus"]
period: 10s
hosts: ["http://127.0.0.1/nginx_status"]
output.elasticsearch:
hosts: ["elasticsearch.internal:9200"]
index: "metricbeat-%{+YYYY.MM.dd}"
Metricbeat отправляет напрямую в Elasticsearch, минуя Logstash - у него нет смысла гонять системные метрики через pipeline с grok-парсингом. Данные уже структурированы самим модулем.
Kibana поставляется с готовыми дашбордами для Metricbeat. Команда metricbeat setup --dashboards импортирует их автоматически. Дашборды показывают CPU, память, дисковые операции, сетевой трафик, load average - стандартный набор, но красиво оформленный и сразу работающий без настройки.
Packetbeat: трогали, но не оставили
Packetbeat - ещё один Beat, который перехватывает сетевой трафик и анализирует протоколы (HTTP, DNS, MySQL, Redis и другие). Мы его запустили на тестовом стенде из любопытства.
Выглядит интересно: видишь все HTTP-запросы с кодами ответов и временем выполнения, DNS-запросы, запросы к базам данных. Но потребление CPU на активном хосте оказалось заметным. Для задачи «понять что происходит с сетью при инциденте» он полезен, для постоянного продакшн-мониторинга не оставили - слишком дорого по ресурсам.
Что получили в итоге
Картина стала заметно чище. Раньше для логирования - logstash-forwarder, для метрик - zabbix-агент и collectd, конфиги разбросаны по разным системам. Сейчас на каждом хосте два Beat-агента: Filebeat для логов, Metricbeat для метрик. Оба конфигурируются через Ansible-роли, оба отдают данные в один стек.
Kibana стала единым местом где можно за минуту посмотреть и логи, и системные метрики по одному хосту - без переключения между интерфейсами Zabbix и Kibana. Для тех кто разбирает инцидент это удобнее чем кажется сначала.
Потребление памяти упало примерно вчетверо по сравнению с logstash-forwarder. Это не цифра из маркетингового листа - это наш мониторинг за три недели на реальных серверах.