Русский
Русский
English
Статистика
Реклама

Filebeat

Elasticsearch сайзинг шардов как завещал Elastic анонс вебинара предложения по митапу

15.03.2021 20:13:27 | Автор: admin

Каждый индекс Elasticsearch состоит из шардов. Шарды это логическое и физическое разделение индекса. В этой статье мы расскажем о сайзинге шардов Elasticsearch важной его части, серьёзно влияющей на производительность кластера. В высоконагруженных системах выбор правильной конфигурации архитектуры хранения позволит серьёзно сэкономить на железе. Бльшая часть статьи основана на соответствующем разделе документации Elastic. Подробности под катом.

Сайзинг шардов Elasicsearch


Как Elasticsearch работает с шардами


Поисковые запросы обычно попадают в несколько шардов (в продукционных нагруженных средах рекомендуем использовать ноду с ролью coordinating). Каждый шард выполняет поисковый запрос в одном процессорном треде. Если запросов много, пул тредов поиска заканчивается (именно поиска, т.к. есть и другие), что приводит к возникновению очередей, снижению производительности и, как следствие, медленной скорости поиска.

Каждый шард использует ресурсы памяти и процессора. Небольшое количество бльших по объёму шардов использует меньше ресурсов, чем множество мелких.

Давайте теперь краем глаза взглянем на сегменты (см. картинку ниже). Каждый шард Elasticsearch является индексом Lucene. Максимальное количество документов, которое можно закинуть в индекс Lucene 2 147 483 519. Индекс Lucene разделен на блоки данных меньшего размера, называемые сегментами. Сегмент это небольшой индекс Lucene. Lucene выполняет поиск во всех сегментах последовательно. Большинство шардов содержат несколько сегментов, в которых хранятся данные индекса. Elasticsearch хранит метаданные сегментов в JVM Heap, чтобы их можно было быстро извлечь для поиска. По мере роста объёма шарда его сегменты объединяются в меньшее количество более крупных сегментов. Это уменьшает количество сегментов, что означает, что в динамической памяти хранится меньше метаданных (см. также forcemerge, к которому мы вернемся чуть дальше в статье).

Еще стоит сказать о ребалансировке кластера. Если добавляется новая нода или одна из нод выходит из строя, происходит ребалансировка кластера. Ребалансировка сама по себе недешёвая с точки зрения производительности операция. Кластер сбалансирован, если он имеет равное количество шардов на каждой ноде и отсутствует концентрация шардов любого индекса на любой ноде. Elasticsearch запускает автоматический процесс, называемый ребалансировкой, который перемещает шарды между узлами в кластере, чтобы его сбалансировать. При перебалансировке применяются заранее заданные правила выделения сегментов (об allocation awareness и других правилах мы подробнее расскажем в одной из следующих статей). Если вы используете data tiers, Elasticsearch автоматически разместит каждый шард на соответствующем уровне. Балансировщик работает независимо на каждом уровне.

Как заставить Elasticsearch ещё лучше работать с шардами


Правильно удалять данные. Если вы удалили документ, из файловой системы он удалится не сразу. Вместо этого, Elasticsearch помечает документ как удаленный на каждом шарде. Отмеченный документ будет продолжать использовать ресурсы, пока он не будет удален во время периодического слияния сегментов. Если нужно физически освободить место, лучше всего сразу удалять индексы целиком, которые в итоге освободят файловую системы.

Создавать шарды размером от 10 до 50 ГБ. Elastic говорит, шарды размером более 50 ГБ потенциально могут снизить вероятность восстановления кластера после сбоя. Из-за той самой ребалансировки, о которой мы говорили в начале статьи. Ну, и большие шарды накладнее передавать по сети. Предел в 50 ГБ выглядит, конечно, как сферический конь в вакууме, поэтому мы сами больше склоняемся к 10 ГБ. Вот тут человек советует 10 ГБ и смотреть на размер документов в следующем плане:

  • От 0 до 4 миллионов документов на индекс: 1 шард.
  • От 4 до 5 миллионов документов на индекс: 2 шарда.
  • Более 5 миллионов документов считать по формуле: (количество документов / 5 миллионов) + 1 шард.

20 или менее шардов на 1 ГБ JVM Heap. Количество шардов, которыми может жонглировать нода, пропорциональны объему JVM Heap ноды. Например, нода с 30 ГБ JVM Heap должна иметь не более 600 шардов. Чем меньше, тем, скорее всего, лучше. Если это пропорция не выполняется можно добавить ноду. Посмотрим сколько там используется JVM Heap на каждой ноде:



А теперь посмотрим сколько шардов на каждой ноде и видим, что с нашим тестовым стендов всё в порядке. Жить будет.



Количество шардов на узле можно ограничить при помощи опции index.routing.allocation.total_shards_per_node, но если их уже много, присмотритесь к Shrink API.

Совсем необязательно создавать индексы размером в 1 день. Часто встречали у заказчиков подход, при котором каждый новый день создавался новый индекс. Иногда это оправдано, иногда можно и месяц подождать. Ролловер ведь можно запускать не только с max_age, но и с max_size или max_docs. На Хабре была статья, в которой Адель Сачков, в ту пору из Яндекс Денег (сейчас уже нет), делился полезным лайфхаком: создавал индексы не в момент наступления новых суток, а заранее, чтобы этот процесс не аффектил на производительность кластера, но у него там были микросервисы.
каждые сутки создаются новые индексы по числу микросервисов поэтому раньше каждую ночь эластик впадал в клинч примерно на 8 минут, пока создавалась сотня новых индексов, несколько сотен новых шардов, график нагрузки на диски уходил в полку, вырастали очереди на отправку логов в эластик на хостах, и Zabbix расцветал алертами как новогодняя ёлка. Чтобы этого избежать, по здравому размышлению был написан скрипт на Python для предварительного создания индексов.

С новогодней ёлкой неплохой каламбурчик получился.

Не пренебрегайте ILM и forcemerge. Индексы должны плавно перетекать между соответствующими нодами согласно ILM. В OpenDistro есть аналогичный механизм.



С индексами, в которые уже не ведется запись можно выполнить forcemerge слияние меньших по размеру сегментов в более крупные. Это в итоге снизит накладные расходы на эксплуатацию шардов и повысит скорость поиска. Forcemerge требует значительных ресурсов, поэтому лучше это делать к какие-то в непиковые часы. Добавим, что forcemerge это фактические создание нового сегмента из двух старых, поэтому свободное место на диске лишним точно не будет.

Приходите в комментарии и расскажите о своём опыте с раскладыванием шардов по нодам. Было бы интересно узнать о том, что работает в вашем случае.

Анонс вебинара. Elastic приглашает посетить 17 марта в 12 часов по московскому времени вебинар Elastic Telco Day: Applications and operational highlights from telco environments. Эксперты расскажут о применении в решений Elastic в телекоме. Регистрация.

Предложения по митапу. Планируем проведение онлайн-митап по Elastic в апреле. Напишите в комментариях или в личку какие темы вам было бы интересно разобрать, каких спикеров услышать. Если бы вы хотели сами выступить и у вас есть что рассказать, тоже напишите. Вступайте в группу Elastic Moscow User Group, чтобы не пропустить анонс митапа.

Канал в телеге. Подписывайтесь на наш канал Elastic Stack Recipes, там интересные материалы и анонсы мероприятий.

Читайте наши другие статьи:




Если вас интересуют услуги внедрения, администрирования и поддержки Elastic Stack, вы можете оставить заявку в форме обратной связи на специальной странице.
Подробнее..

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

02.04.2021 12:23:26 | Автор: admin

В комментариях к моему туториалу, рассказывающему о парсинге логов с помощью Fluent-bit, было приведено две альтернативы: Filebeat и Vector. Этот туториал рассказывает как организовать сбор и парсинг лог-сообщений при помощи Filebeat.


Цель туториала: Организовать сбор и парсинг лог-сообщений с помощью Filebeat.


Дисклеймер: Туториал не содержит готовых для продакшена решений, он написан с целью помочь тем кто только начинает разбираться с filebeat и для закрепления изученного материала автором. Так же в туториале не проводиться сравнение доставщиков логов. Сравнение можно найти здесь.


Кому данная тема интересна, прошу под кат:)


Тестовое приложение будем запускать с помощью docker-compose.


Общая информация


Filebeat это легковесный доставщик лог-сообщений. Принцип его работы состоит в мониторинге и сборе лог-сообщений из лог-файлов и пересылки их в elasticsearch или logstash для индексирования.


Filebeat состоит из ключевых компонентов:


  • сборщики (harvesters) отвечают за чтение лог-файлов и отправку лог-сообщений в заданный выходной интерфейс, на каждый лог-файл задается отдельный сборщик;
  • входные интерфейсы (inputs) отвечают за поиск источников лог-сообщений и управление сборщиками.

Подробнее о принципе работы можно почитать в официальном руководстве.


Организация сбора лог-сообщений


Filebeat имеет множество входных интерфейсов для различных источников лог-сообщений. В рамках туториала предлагаю двигаться от настройки сбора вручную до автоматического поиска источников лог-сообщений в контейнерах. По моему мнению данный подход позволит глубже понять filebeat, к тому же я сам двигался тем же путем.


Нам необходим сервис, лог-сообщения которого будем пересылать на хранение.
В качестве такого сервиса возьмем простое приложение, написанное с помощью FastAPI, единственной целью которого является генерация лог-сообщений.


Сбор лог-сообщений с помощью volume


Для начала клонируем репозиторий. В нем находится тестовое приложение, конфигурационный файл Filebeat и docker-compose.yml.
Настройка сбора лог-сообщений с помощью volume состоит из следующих шагов:


  1. Настройка логгера приложения на запись лог-сообщений в файл:
    app/api/main.py
    logger.add(    "./logs/file.log",    format="app-log - {level} - {message}",    rotation="500 MB")
    
  2. Создание 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/logvolumes:  app-logs:
    

  3. Определение входного и выходного интерфейсов 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 состоит из следующих шагов:


  1. Удаление настроек входного интерфейса log, добавленного на предыдущем этапе, из конфигурационного файла.
  2. Определение входного интерфейса container в конфигурационном файле:
    filebeat.docker.yml


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

  3. Отключаем volume app-logs из сервисов app и log-shipper и удаляем его, он нам больше не понадобиться.
  4. Подключаем к сервису 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
    

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

Входной интерфейс container, настроенный таким образом, будет собирать лог-сообщения со всех контейнеров, однако может потребоваться собирать лог-сообщения только с определенных контейнеров.
Это можно сделать описанным ниже способом.


Сбор лог-сообщений с помощью автообнаружения


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


  • шаблона поиска контейнера;
  • конфигурации сбора лог-сообщений.

Подробнее можно почитать здесь.


Настройка состоит из следующих шагов:


  1. Удаление настроек входного интерфейса container, добавленного на предыдущем этапе, из конфигурационного файла.
  2. Определение настроек автообнаружение в конфигурационном файле:
    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 проверит, содержит ли он какие-либо подсказки, и запустит для него сбор с правильной конфигурацией.


Подробнее можно почитать здесь.


Настройка сбора состоит из следующих шагов:


  1. Удаляем шаблон обнаружения сервиса app и включаем подсказки:
    filebeat.docker.yml


    filebeat.autodiscover:  providers:    - type: docker      hints.enabled: true# Пока будем выводить лог-сообщения в консольoutput.console:  pretty: true
    

  2. Отключаем сбор лог-сообщения для сервиса log-shipper:
    docker-compose.yml


    version: "3.8"services:  app:    ...  log-shipper:    ...    labels:      co.elastic.logs/enabled: "false"
    


Парсинг лог-сообщений


Для обработки лог-сообщений в Filebeat есть большое количество обработчиков (processors).
Их можно подключить с помощью лейблов контейнеров либо определить в конфигурационном файле.
Воспользуемся вторым способом.


  1. Для начала очистим лог-сообщения от метаданных. Для этого в конфигурационный файл добавим обработчик 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"]}
    

  2. Для отделения лог-сообщений API от лог-сообщений asgi-сервера, добавим к ним тег с помощью обработчика add_tags:
    filebeat.docker.yml


    processors:  - drop_fields:      ...  - add_tags:    when:      contains:        "message": "app-log"    tags: [test-app]    target: "environment"
    

  3. Структурируем поле 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.


Всем спасибо за внимание!

Подробнее..
Категории: Devops , Elasticsearch , Filebeat

Из песочницы Spring Boot и Filebeat локально без регистрации и смс

22.10.2020 12:07:47 | Автор: admin

В данном руководстве мы рассмотрим подключение и настройку системы логирования в Spring Boot проекте и отправку логов в ELK с помощью Filebeat. Руководство предназначено для разработчиков начального уровня.


Логирование и зачем оно нужно


Когда я только начинал работать программистом один мой старший коллега любил повторять: "Если у тебя нет логов, то у тебя нет ничего". Действительно, столкнувшись с первым же багом на тестовых стендах или хуже того в промышленной среде, первое что нам будет нужно это логи приложения и удобный доступ к ним. За сами логи отвечают разработчики приложения, которые должны обеспечить логирование поведения системы таким образом, чтобы в любой момент можно было понять что происходит с системой и главное что с ней не так.


Следующий вопрос, это удобство доступа к логам. Обычно при локальном тестировании мы видим лог в консоли приложения, а на тестовым стенде в специальных лог файлах на сервере. Удобно ли и безопасно ли каждый раз подключаться к стенду, искать нужную директорию и читать файлы логов оттуда? Практика показывает что нет и это вторая проблема которую призван решить ряд продуктов, обеспечивающих удобный доступ к логам и поиск в них важной информации. Сегодня мы очень кратко поговорим о одной из групп таких продуктов, так называемом стеке ELK (Elasticsearch Logstash Kibana) и более подробно о Filebeat Open source продукте, обеспечивающем удобный механизм доставки логов до ELK.


Три строчки о ELK


  • Logstash получение, модификация логов
  • Elasticsearch хранение и поиск
  • Kibana отображение

Причем здесь Filebeat?


Filebeat обеспечит доставку данных до ELK и будет разворачиваться рядом с нашим приложением, зачастую это просто удобнее чем настраивать Logstash для того чтобы читать данные из файлов логов или иных каналов.


Хорошим подходом будет развертывание общего ELK для группы микросервисов, а для каждого микросервиса разворачивать свой Filebeat (тем более что это проще некуда), который будет читать логи микросервиса и отдавать в общий ELK.


Именно такое решение мы попробуем реализовать позже в локальной среде.



Практика


Java 8
ApacheMaven3.6
Spring Boot 2.3.4.RELEASE
Docker


Spring Boot App


Начнем с создания простого Spring Boot приложения, единственной задачей которого будет генерировать логи по запросу. Полный код приложения можно посмотреть/скачать здесь либо повторить по шагам


Создадим проект Spring Boot самостоятельно или используя Spring Initalizr


Дополнительно нам понадобятся зависимости


<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-web</artifactId></dependency><dependency>    <groupId>net.logstash.logback</groupId>    <artifactId>logstash-logback-encoder</artifactId>    <version>6.4</version></dependency><dependency>    <groupId>org.projectlombok</groupId>    <artifactId>lombok</artifactId></dependency>

  • spring-boot-starter-web т.к. мы будем обращаться к приложению по сети
  • logstash-logback-encoder позволит сформировать записи в лог файле в правильном формате
  • lombok просто для удобства, чтобы писать меньше кода

Здесь полный pom.xml


Главный класс нашего приложения как и в любом простейшем Spring Boot проекте:


@SpringBootApplicationpublic class Application {    public static void main(String[] args) {        SpringApplication.run(Application.class, args);    }}

Класс генератор который будет создавать логи:


@Slf4j@Servicepublic class LogGenerator {    public void generate(int count) {        log.info("Start generating logs");        LongStream.range(0, count)                .forEach(i -> log.info("Log {}", i));    }}

Здесь мы просто создаем от 0 до count записей в логе


Контроллер, который мы будем вызывать для обращения к генератору:


@Slf4j@RestController@RequiredArgsConstructorpublic class LogController {    private final LogGenerator generator;    @GetMapping("/generate")    public ResponseEntity test(@RequestParam(name = "count", defaultValue = "0") Integer count) {        log.info("Test request received with count: {}", count);        generator.generate(count);        return ResponseEntity.ok("Success!");    }}

Контроллер обрабатывает GET запросы вида:
http://localhost:8080/generate?count=10
и запускает генератор передавая ему количество записей


Теперь настроим систему логирования. Для этого добавим в resources файл logback-spring.xml


<?xml version="1.0" encoding="UTF-8"?><configuration>    <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">        <encoder>            <pattern>%d [%thread] %-5level  %logger{35} - [%mdc] - %msg%n</pattern>        </encoder>    </appender>    <appender name="filebeatAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">        <file>./log/application.log</file>        <append>true</append>        <encoder class="net.logstash.logback.encoder.LogstashEncoder"/>        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">            <fileNamePattern>./log/application.%d.%i.log.gz</fileNamePattern>            <maxFileSize>10MB</maxFileSize>        </rollingPolicy>    </appender>    <root level="INFO">        <appender-ref ref="consoleAppender" />        <appender-ref ref="filebeatAppender" />    </root></configuration>

Здесь мы обьявили два аппендера:


  • consoleAppender пишет записи согласно указанному нами паттерну в привычную нам консоль
  • filebeatAppender пишет записи в файл, причем в качестве енкодера используется LogstashEncoder из той самой библиотеки logstash-logback-encoder
    Назначения данного енкодера кодировать файлы логов в JSON формат, который легко будет понимать Logstash. В противном случае нужно будет конфигурировать сам Logstash что снижает универсальность нашего решения и просто добавит лишней работы по настройке.

Как видно из кода, файл лога будет писаться согласно пути ./log/application.log что соответствует поддиректории log в папке с проектом. Разумеется можно указать любой другой путь. Также при желании можно скорректировать максимальный размер файла maxFileSize


На самом деле на этом можно было бы закончить и перейти к установки и настройке Filebeat но мы сделаем еще кое что.


Добавим в наш проект класс фильтр для запросов:


@Slf4j@Componentpublic class LogFilter extends OncePerRequestFilter {    private static final String REQUEST_ID = "requestId";    @Override    protected void doFilterInternal(HttpServletRequest request,                                    HttpServletResponse response,                                    FilterChain filterChain) throws ServletException, IOException {        String requestId = request.getHeader(REQUEST_ID);        if (requestId == null) {            requestId = UUID.randomUUID().toString();        }        MDC.put(REQUEST_ID, requestId);        try {            log.info("Started process request with {} : {}", REQUEST_ID, requestId);            filterChain.doFilter(request, response);        } finally {            MDC.clear();        }    }}

Назначения этого класса, перехватывать все запросы к контроллеру и генерировать уникальный идентификатор запроса (если таковой не был отправлен в виде хедера requestId), после чего помещает его в MDC (Mapped Diagnostic Context)


MDC.put(REQUEST_ID, requestId);

А finally блоке MDC будет очищаться


MDC.clear();

Ценность такого подхода в том, что теперь все логи записанные в рамках конкретного запроса объединены единым уникальным идентификатором, что может облегчить анализ логов при разборе инцидентов. Дальше мы увидим как просто в интерфейсе Kibana можно будет отфильтровать только логи для каждого конкретного запроса.


После того как ваше приложение будет закончено, запустите его удобным для вас способом, например:


mvn spring-boot:run

После того как приложение стартует, можно вызвать его и убедиться что логи пишутся в файла application.log


curl "localhost:8080/generate?count=10"

Сервис должен отвечать Success!, а в application.log появлятся записи вида:


{   "@timestamp":"2020-10-17T22:39:45.595+03:00",   "@version":"1",   "message":"Writing [\"Success!\"]",   "logger_name":"org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor",   "thread_name":"http-nio-8080-exec-3",   "level":"INFO",   "level_value":10000,   "requestId":"77abe5ac-4458-4dc3-9f4e-a7320979e3ae"}

Filebeat


Скачать можно по ссылке Filebeat
В рамках данной статья тестирование проводилось на версии 7.9.2 на macOS
Далее следует распаковать дистрибутив в необходимую директорию.
Для настройки Filebeat вам понадобится всего лишь скорректировать содержимое файла filebeat.xml


Конфигурация уже почти готова, нам нужно только скорректировать блоки inputs и output:


  inputs:  - enabled: true    encoding: utf-8    exclude_files: ['\.gz$']    json:      add_error_key: true      keys_under_root: true      overwrite_keys: true    paths:    - {ваш путь до папки с логами}/*.log    scan_frequency: 10s    type: log

Здесь самое главное, мы указываем Filebeat где лежат файлы логов и как их следует интерпретировать. Для этого мы добавим следующие параметры:


  • keys_under_root наши логи в формате json будут встраивались в существующий json, который Filebeat будет отправлять в Logstash
  • overwrite_keys позволит перезаписывать ключи полей и корректно разрешать конфликты
  • add_error_key Filebeat будет добавлять поля error.message и error.type: json в случае если сформированный нами json оказался некорректным.

output:  logstash:    hosts:    - localhost:5044    ssl:      certificate_authorities:      - {путь до папки с сертификатами}/logstash-beats.crt

Этот блок отвечает за то, куда Filebeat будет отправлять логи. В данном случае указан дефолтный порт с которым будет запущен Logstash (если вы умышленно не будете запускать его на другом порту)
блок ssl.certificate_authorities не обязательный и понадобится в случае если вы будете использовать Logstash защищенный сертификатами (именно такой будем рассматривать мы), в противном случае он вам не нужен.


Этих настроек достаточно для локальной работы Filebeat, за тем лишь исключением что пока ему некуда отдавать данные, т.к. ELK еще не запущен.
Вопрос полного развертывания и конфигурирования всех компонентов ELK выходит за рамки данной статьи. Для упрощения, предлагается воспользоваться готовым docker образом ELK sebp/elk и также предлагается воспользоваться logstash-beats.crt. Его следует скачать и прописать как certificate_authorities в filebeat.xml


Автор запускает посредством docker-compose с пробросом портов:


version: '3.7'services:  elk:    image: sebp/elk    ports:      - "5601:5601" #kibana      - "9200:9200" #elastic      - "5044:5044" #logstash

После запуска ELK можно запустить и Filebeat соответствующей командой в зависимости от вашей операционной систему, например для macOS это:


./filebeat -e run

Что происходит? Наше приложение по запросу генерирует логи, они с помощью LogstashEncoder преобразуются к виду JSON и записываются в файл application.log, а Filebeat в свою очереди регулярно забирает новые записи, преобразует их в соответствии со своей конфигурацией и отправляет в Logstash. Далее с этими данными мы можем работать в интерфейсе Kibana.


Зайдем в интерфейс Kibana по адресу:
http://localhost:5601/


Далее перейдем на вкладку Discover:



Нужно будет создать индекс паттерн:



Затем Kibana покажет вам index от которого ELK уже получил данные. Важно! Если ваше приложение еще ничего не залогировало или Filebeat не успел ничего отправить, то и индекса не появится на этой вкладки. Потому прежде сделайте несколько вызовов нашего сервиса:


curl "localhost:8080/generate?count=100"

Немного подождем и можно будет определить нужный паттерн:



Выберем поля для дефолтной сортировки:



И увидим поля для каждой лог записи нашего приложения. Можно увидеть тот самый requestId который был нами добавлен в MDC ранее:



Теперь во вкладке Discover для нашего индекса можно настроить отображения полей и увидеть, что все логи в рамках одного запроса объединены одним и тем же requestId. Можно развернуть поле JSON и посмотреть полный текст сообщения полученного из Filebeat:


Подробнее..
Категории: Java , Логирование , Spring boot , Filebeat

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru