Pipeline Logstash: input, filter, output

Анатомия конфигурации Logstash: три секции, через которые проходит каждое событие.

Pipeline Logstash — конвейер из трёх секций: input (откуда брать события), filter (как их преобразовать) и output (куда отправить).

Зачем нужен Logstash, если есть ingest-пайплайны

Мы видели, что Filebeat умеет писать в ES напрямую через ingest-пайплайн. Зачем тогда Logstash? Когда обработка сложная — несколько источников, ветвления по типу лога, обогащение из внешних баз, маршрутизация в разные индексы, буферизация большого потока — Logstash удобнее и мощнее. Это полноценный движок обработки, а не набор процессоров. На больших и разнородных потоках логов он остаётся рабочей лошадкой.

Три секции конфигурации

Конфиг Logstash (logstash.conf) почти всегда состоит из трёх блоков. Вот сквозной пример: принять события от Filebeat, разобрать лог nginx и отправить в Elasticsearch.

input {
  beats {
    port => 5044
  }
}

filter {
  grok {
    match => { "message" => "%{COMBINEDAPACHELOG}" }
  }
  date {
    match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
  }
}

output {
  elasticsearch {
    hosts => ["http://es01:9200"]
    index => "logs-nginx-%{+YYYY.MM.dd}"
  }
}

Обратите внимание на синтаксис => (это стрелка = плюс >, оператор присваивания в языке конфигурации Logstash) и фигурные скобки секций.

input

Откуда брать события. Самый частый для логов — beats (приём от Filebeat по порту 5044). Есть десятки других: file, kafka, syslog, tcp, http. Здесь же Logstash может читать из буферной очереди Kafka.

filter

Сердце Logstash. Цепочка фильтров, которые по очереди преобразуют событие: grok разбирает строку на поля, date приводит время, mutate правит поля, geoip добавляет геолокацию. Фильтры применяются сверху вниз — порядок важен.

output

Куда отправить. Обычно elasticsearch, но бывает file, kafka, stdout (для отладки), и даже несколько выходов сразу.

Как работает под капотом: воркеры и батчи

Logstash обрабатывает события не по одному, а батчами, в несколько параллельных воркеров (по числу ядер). Событие из input попадает в внутреннюю очередь, воркер забирает батч, прогоняет через все фильтры и шлёт в output. По умолчанию очередь в памяти (быстро, но теряется при падении), но можно включить persistent queue на диске — тогда события переживут перезапуск Logstash.

  input --> [ очередь ] --> воркер 1: filter -> output
                       --> воркер 2: filter -> output
                       --> воркер N: filter -> output

  persistent queue на диске = события переживут рестарт

Условная логика

В filter и output можно ветвиться по полям события. Например, логи nginx парсить одним grok, логи приложения — другим, а в ES слать в разные индексы:

filter {
  if [log_type] == "nginx-access" {
    grok { match => { "message" => "%{COMBINEDAPACHELOG}" } }
  } else if [log_type] == "app" {
    json { source => "message" }
  }
}

Где Logstash, а где ingest-пайплайн

Поскольку у Logstash и ingest-пайплайнов Elasticsearch пересекающиеся возможности (оба умеют grok, оба обогащают), полезно иметь ясный критерий выбора. Ingest-пайплайн живёт внутри Elasticsearch, не требует отдельной инфраструктуры и отлично подходит, когда обработка простая и поток умеренный — он экономит вам целый отдельный сервис. Logstash оправдан, когда появляется хотя бы одно из: несколько разнородных источников с разной логикой разбора, потребность в буферизации большого потока, обогащение из внешних систем (база соответствий, HTTP-запросы), маршрутизация в несколько выходов или необходимость снять нагрузку обработки с самого кластера ES. Грубо говоря, ingest-пайплайн — это «лёгкая обработка по пути в хранилище», а Logstash — «полноценный ETL для логов» со своей памятью, очередью и масштабированием.

На больших инсталляциях часто встречается гибрид: Filebeat собирает, Kafka буферизует, Logstash делает тяжёлую обработку и нормализацию, а финальную лёгкую доводку (например, добавление поля окружения) делает уже ingest-пайплайн в ES. Каждый инструмент на своём месте — это нормальная зрелая архитектура, а не избыточность.

Частые ошибки

  • Неверный порядок фильтров. Если date стоит до grok, который ещё не извлёк поле timestamp, парсинг времени провалится. Фильтры идут сверху вниз — учитывайте зависимости.
  • Очередь в памяти на проде. Дефолтная in-memory очередь теряет события при краше. Для важных логов включайте persistent queue.
  • Logstash там, где хватило бы ingest-пайплайна. Тяжёлый Logstash ради разбора одного простого формата — оверкилл; иногда достаточно Filebeat + ingest ES.

Итоги

  • Pipeline Logstash = input (источник) → filter (преобразование) → output (назначение).
  • Фильтры применяются по порядку сверху вниз; порядок критичен (например, grok перед date).
  • Внутри — батчи, параллельные воркеры и очередь; persistent queue спасает события при перезапуске.
  • Logstash берут для сложной обработки; для простых случаев хватает ingest-пайплайна ES.
Проверьте себя
1. Из каких трёх секций состоит pipeline Logstash?
Aread, process, write
Binput, filter, output
Csource, transform, sink
Dcollect, parse, store
2. Почему важен порядок фильтров в секции filter?
ALogstash выполняет их случайно, порядок неважен
BФильтры применяются сверху вниз, и один фильтр может зависеть от поля, созданного предыдущим
CПорядок влияет только на скорость
DПоследний фильтр всегда выполняется первым
3. Что даёт включение persistent queue в Logstash?
AУскоряет grok-парсинг
BСобытия сохраняются на диск и переживают перезапуск Logstash, а не теряются как в in-memory очереди
CАвтоматически создаёт индексы в Elasticsearch
DСжимает события