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

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. Это не цифра из маркетингового листа - это наш мониторинг за три недели на реальных серверах.

Контакт

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

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