[DevOps] Организация сбора и парсинга логов при помощи Filebeat

Автор Сообщение
news_bot ®

Стаж: 6 лет 9 месяцев
Сообщений: 27286

Создавать темы news_bot ® написал(а)
02-Апр-2021 14:32

В комментариях к моему туториалу, рассказывающему о парсинге логов с помощью Fluent-bit, было приведено две альтернативы: Filebeat и Vector. Этот туториал рассказывает как организовать сбор и парсинг лог-сообщений при помощи Filebeat.
Цель туториала: Организовать сбор и парсинг лог-сообщений с помощью Filebeat.
Дисклеймер: Туториал не содержит готовых для продакшена решений, он написан с целью помочь тем кто только начинает разбираться с filebeat и для закрепления изученного материала автором. Так же в туториале не проводиться сравнение доставщиков логов. Сравнение можно найти здесь.
Кому данная тема интересна, прошу под кат:)
Тестовое приложение будем запускать с помощью docker-compose.
Общая информация
Filebeat — это легковесный доставщик лог-сообщений. Принцип его работы состоит в мониторинге и сборе лог-сообщений из лог-файлов и пересылки их в elasticsearch или logstash для индексирования.
Filebeat состоит из ключевых компонентов:
  • сборщики (harvesters) — отвечают за чтение лог-файлов и отправку лог-сообщений в заданный выходной интерфейс, на каждый лог-файл задается отдельный сборщик;
  • входные интерфейсы (inputs) — отвечают за поиск источников лог-сообщений и управление сборщиками.

Подробнее о принципе работы можно почитать в официальном руководстве.
Организация сбора лог-сообщений
Filebeat имеет множество входных интерфейсов для различных источников лог-сообщений. В рамках туториала предлагаю двигаться от настройки сбора вручную до автоматического поиска источников лог-сообщений в контейнерах. По моему мнению данный подход позволит глубже понять filebeat, к тому же я сам двигался тем же путем.
Нам необходим сервис, лог-сообщения которого будем пересылать на хранение.
В качестве такого сервиса возьмем простое приложение, написанное с помощью FastAPI, единственной целью которого является генерация лог-сообщений.
Сбор лог-сообщений с помощью volume
Для начала клонируем репозиторий. В нем находится тестовое приложение, конфигурационный файл Filebeat и docker-compose.yml.
Настройка сбора лог-сообщений с помощью volume состоит из следующих шагов:
  • Настройка логгера приложения на запись лог-сообщений в файл:
    app/api/main.py
    logger.add(
        "./logs/file.log",
        format="app-log - {level} - {message}",
        rotation="500 MB"
    )
  • Создание volume для хранения лог-файлов вне контейнеров:
    docker-compose.yml
    version: "3.8"
    services:
      app:
        ...
        volumes:
          # создаем volume, для хранения лог-файлов вне контейнера
          - app-logs:/logs
      log-shipper:
        ...
        volumes:
          # заменяем конфигурационный файл в контейнере
          - ./filebeat.docker.yml:/usr/share/filebeat/filebeat.yml:ro
          # подключаем volume с лог-файлами в контейнер
          - app-logs:/var/app/log
    volumes:
      app-logs:

  • Определение входного и выходного интерфейсов filebeat:
    filebeat.docker.yml
    filebeat.inputs:
    - type: log
      # Определяем путь к лог-файлам
      paths:
        - /var/app/log/*.log
    # Пока будем выводить лог-сообщения в консоль
    output.console:
      pretty: true

    Запускаем тестовое приложение, генерируем лог-сообщения и получаем их в следующем формате:
    {
    "@timestamp": "2021-04-01T04:02:28.138Z",
    "@metadata": {
    "beat": "filebeat",
    "type": "_doc",
    "version": "7.12.0"
    },
    "ecs": {
    "version": "1.8.0"
    },
    "host": {
    "name": "aa9718a27eb9"
    },
    "message": "app-log - ERROR - [Item not found] - 1",
    "log": {
    "offset": 377,
    "file": {
      "path": "/var/app/log/file.log"
    }
    },
    "input": {
    "type": "log"
    },
    "agent": {
    "version": "7.12.0",
    "hostname": "aa9718a27eb9",
    "ephemeral_id": "df245ed5-bd04-4eca-8b89-bd0c61169283",
    "id": "35333344-c3cc-44bf-a4d6-3a7315c328eb",
    "name": "aa9718a27eb9",
    "type": "filebeat"
    }
    }


Сбор лог-сообщений с помощью входного интерфейса container
Сontainer позволяет осуществлять сбор лог-сообщений с лог-файлов контейнеров.
Настройка сбора лог-сообщений с помощью входного интерфейса container состоит из следующих шагов:
  • Удаление настроек входного интерфейса log, добавленного на предыдущем этапе, из конфигурационного файла.
  • Определение входного интерфейса container в конфигурационном файле:
    filebeat.docker.yml
    filebeat.inputs:
    - type: container
      # путь к лог-файлам контейнеров
      paths:
        - '/var/lib/docker/containers/*/*.log'
    # Пока будем выводить лог-сообщения в консоль
    output.console:
      pretty: true

  • Отключаем volume app-logs из сервисов app и log-shipper и удаляем его, он нам больше не понадобиться.
  • Подключаем к сервису log-shipper лог-файлы контейнеров и сокет докера:
    docker-compose.yml
    version: "3.8"
    services:
      app:
        ...
      log-shipper:
        ...
        volumes:
          # заменяем конфигурационный файл в контейнере
          - ./filebeat.docker.yml:/usr/share/filebeat/filebeat.yml:ro
          - /var/lib/docker/containers:/var/lib/docker/containers:ro
          - /var/run/docker.sock:/var/run/docker.sock:ro

  • Настройка логгера приложения на запись лог-сообщений в стандартный вывод:
    app/api/main.py
    logger.add(
        sys.stdout,
        format="app-log - {level} - {message}",
    )

Входной интерфейс container, настроенный таким образом, будет собирать лог-сообщения со всех контейнеров, однако может потребоваться собирать лог-сообщения только с определенных контейнеров.
Это можно сделать описанным ниже способом.
Сбор лог-сообщений с помощью автообнаружения
При сборе лог-сообщений контейнеров, могут возникнуть трудности, так как контейнеры могут перезапускаться, удаляться и т.д. В связи с этим в filebeat есть автообнаружение контейнеров, с возможностью определения настроек сбора лог-сообщений для каждого обнаруженного контейнера. Механизм автообнаружения состоит из двух частей:
  • шаблона поиска контейнера;
  • конфигурации сбора лог-сообщений.

Подробнее можно почитать здесь.
Настройка состоит из следующих шагов:
  • Удаление настроек входного интерфейса container, добавленного на предыдущем этапе, из конфигурационного файла.
  • Определение настроек автообнаружение в конфигурационном файле:
    filebeat.docker.yml
    filebeat.autodiscover:
      providers:
        # искать docker контейнер
        - type: docker
          templates:
            - condition:
                contains:
                  # имя которого fastapi_app
                  docker.container.name: fastapi_app
              # определим конфигурацию сбора для этого контейнера
              config:
                - type: container
                  paths:
                    - /var/lib/docker/containers/${data.docker.container.id}/*.log
                  # исключим лог-сообщения asgi-сервера
                  exclude_lines: ["^INFO:"]
    # Пока будем выводить лог-сообщения в консоль
    output.console:
      pretty: true


Вот и все. Теперь filebeat будет собирать лог-сообщения только с указанного контейнера.
Сбор лог-сообщений с использованием подсказок (hints)
Filebeat поддерживает автообнаружение на основе подсказок.
Он ищет информацию (подсказки) о конфигурации сбора в лейблах контейнера.
Как только контейнер запустится, Filebeat проверит, содержит ли он какие-либо подсказки, и запустит для него сбор с правильной конфигурацией.
Подробнее можно почитать здесь.
Настройка сбора состоит из следующих шагов:
  • Удаляем шаблон обнаружения сервиса app и включаем подсказки:
    filebeat.docker.yml
    filebeat.autodiscover:
      providers:
        - type: docker
          hints.enabled: true
    # Пока будем выводить лог-сообщения в консоль
    output.console:
      pretty: true

  • Отключаем сбор лог-сообщения для сервиса log-shipper:
    docker-compose.yml
    version: "3.8"
    services:
      app:
        ...
      log-shipper:
        ...
        labels:
          co.elastic.logs/enabled: "false"


Парсинг лог-сообщений
Для обработки лог-сообщений в Filebeat есть большое количество обработчиков (processors).
Их можно подключить с помощью лейблов контейнеров либо определить в конфигурационном файле.
Воспользуемся вторым способом.
  • Для начала очистим лог-сообщения от метаданных. Для этого в конфигурационный файл добавим обработчик drop_fields:
    filebeat.docker.yml
    processors:
      - drop_fields:
          fields: ["agent", "container", "ecs", "log", "input", "docker", "host"]
          ignore_missing: true

    Теперь лог-сообщение выглядит следующим образом:
    {
      "@timestamp": "2021-04-01T04:02:28.138Z",
      "@metadata": {
        "beat": "filebeat",
        "type": "_doc",
        "version": "7.12.0"
      },
      "message": "app-log - ERROR - [Item not found] - 1",
      "stream": ["stdout"]
    }

  • Для отделения лог-сообщений API от лог-сообщений asgi-сервера, добавим к ним тег с помощью обработчика add_tags:
    filebeat.docker.yml
    processors:
      - drop_fields:
          ...
      - add_tags:
        when:
          contains:
            "message": "app-log"
        tags: [test-app]
        target: "environment"

  • Структурируем поле message лог-сообщения с помощью обработчика dissect и удалим его с помощью drop_fields:
    filebeat.docker.yml
    processors:
      - drop_fields:
        ...
      - add_tags:
        ...
    - dissect:
         when:
           contains:
             "message": "app-log"
         tokenizer: 'app-log - %{log-level} - [%{event.name}] - %{event.message}'
         field: "message"
         target_prefix: ""
    - drop_fields:
         when:
           contains:
             "message": "app-log"
         fields: ["message"]
         ignore_missing: true

    Теперь лог-сообщение выглядит следующим образом:
    {
      "@timestamp": "2021-04-02T08:29:07.349Z",
      "@metadata": {
        "beat": "filebeat",
        "type": "_doc",
        "version": "7.12.0"
      },
      "log-level": "ERROR",
      "event": {
        "name": "Item not found",
        "message": "Foo"
      },
      "environment": [
        "test-app"
      ],
      "stream": "stdout"
    }


Дополнение
Filebeat так же имеет готовые решения сбора и парсинга лог-сообщений для широко используемых инструментов таких, как Nginx, Postgres и т.д.
Они называются модулями.
К примеру для сбора лог-сообщений Nginx, достаточно добавить к его контейнеру лейбл:
co.elastic.logs/module: "nginx"

и включить подсказки в конфигурационном файле. После этого мы получим готовое решение для сбора и парсинга лог-сообщений + удобный dashboard в Kibana.
Всем спасибо за внимание!
===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_devops, #_filebeat, #_elasticsearch, #_devops
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 25-Ноя 23:13
Часовой пояс: UTC + 5