Извлекайте пары ключ-значение из строк журнала с помощью парсера FluentD

«Fluentd - это кроссплатформенный проект программного обеспечения для сбора данных с открытым исходным кодом, изначально разработанный в Treasure Data. Он написан в основном на языке программирования Ruby ».

- Википедия

В своих предыдущих сообщениях в блоге я объяснил, как использовать FluentD для анализа и отправки журналов на централизованный сервер журналов (стек EFK), проанализировать многострочные журналы для приложений Rails и представил обзор некоторых из наиболее часто используемых плагинов для анализа журналов. с FluentD. Вы можете проверить упомянутые сообщения в блоге по ссылкам ниже:







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

Проблема

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

По умолчанию FlunetD будет рассматривать приведенную выше строку журнала как длинный текст, и вы не сможете фильтровать журналы в Kibana на основе method или format ответа. Можно извлечь ключи из лога и добавить их к ключам событий с помощью парсера Regex или парсера значения ключа. Однако эти решения имеют некоторые ограничения и работают только в том случае, если вы точно знаете ключи, которые будут присутствовать в строке журнала, или строки содержат только пары ключ-значение (без простого текста).

В моем случае ключи строк журнала были динамическими в зависимости от запроса или события. Следовательно, я не мог использовать парсер Regex, и я не мог также использовать парсер значения ключа, поскольку строки журнала содержат префикс обычного текста для времени события 😢.

Решение

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

Требования необходимых парсеров FluentD кратко представлены ниже:

  • Исходный ключ должен быть настраиваемым. Парсер должен позволять мне извлекать ключи не только из ключа сообщения, но и для любых ключей, определенных в событии FluentD.
  • Включение / отключение удаления исходного ключа после извлечения ключей.
  • Включение / отключение игнорирования строк журнала, в которых не было найдено ключей.
  • Игнорировать и не сканировать простой текст перед парами "ключ-значение".
  • Поддержка стратегий буксировки для извлечения пар ключ-значение. Первый основан на предопределенных разделителях, а второй - на определенном регулярном выражении.
  • Поддержка игнорирования некоторых извлеченных ключей. (Ключи, которые мы хотели бы скрыть от системы логирования)

Реализация

После некоторого исследования я обнаружил, что лучший способ реализовать это решение - создать плагин FluentD Filter с указанными ниже элементами конфигурации для поддержки необходимой функциональности.

  • key: исходный ключ, содержащий сообщение для анализа. Значение по умолчанию - log.
  • remove_key: логический индикатор для удаления исходного ключа после извлечения пар ключ-значение. Значение по умолчанию - false.
  • filter_out_lines_without_kesy: логическое значение, позволяющее удалить строку журнала, если строка журнала не содержит каких-либо определенных пар ключ-значение. Значение по умолчанию - false.
  • use_regex: включить / отключить использование регулярного выражения для извлечения пар ключ-значение. Значение по умолчанию - false.
  • remove_prefix: регулярное выражение, которое будет использоваться для удаления префикса сообщения журнала. По умолчанию значение этого элемента конфигурации пусто.
  • keys_delimiter: Символ, используемый для отделения ключей друг от друга. Значение по умолчанию - пробел.
  • kv_delimter_char: символ, используемый для отделения ключей от их значений. Значение по умолчанию - =.
  • filtered_keys: ключи из белого списка, которые будут включены в событие FluentD.
  • filtered_keys_regex: регулярное выражение для определения ключей из белого списка.

Интеграция подключаемого модуля FluentD с конфигурацией FluentD довольно проста и не требует больших усилий. Следующие ниже шаги суммируют необходимые действия для успешной интеграции фильтра FluentD со сценариями вставки.

  • Установите гем и сделайте его доступным для ваших скриптов FluentD. Если вы используете FluentD в контейнере докера, убедитесь, что гем включен в образ докера. В приведенном ниже примере показано, как создать образ докера FluentD с файлом fluent-plugin-filter-kv-parser.
  • Расширьте конфигурации FluentD, чтобы начать анализ и фильтрацию сообщений журнала. Минимальные конфигурации, которые можно добавить, показаны во фрагменте ниже.

С указанным выше определением фильтра гем будет использовать значения по умолчанию для каждой из определенных конфигураций. Значения по умолчанию можно найти здесь. Это означает, что ключ log будет использоваться в качестве исходного ключа для извлечения пар ключ-значение и не будет удален из Fluentd. Ключи будут извлечены с использованием разделителя по умолчанию, а не с использованием определенного регулярного выражения, и все извлеченные ключи будут добавлены в событие fluent.

Расширение конфигураций фильтра FluentD для изменения поведения извлечения ключей может быть выполнено просто путем добавления необходимых элементов конфигурации в определение фильтра. Например, приведенное ниже определение отфильтрует сообщение журнала и утвердит только те ключи, которые соответствуют заданному регулярному выражению.

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

Фильтр «ключ-значение» FluentD также поддерживает определение и смешивание конфигураций. Например, можно добавить ключи в белый список с регулярным выражением и точными именами одновременно. В этом случае фильтр будет включать все ключи, которые соответствуют регулярному выражению или точным предоставленным ключам.

Заключение

FlunetD - отличный инструмент, который можно использовать для анализа журналов и отправки их на централизованный сервер. Существует множество плагинов и библиотек, которые могут улучшить анализ журналов и решить множество проблем, связанных с анализом журналов. Вдобавок, расширение функциональности логов, анализирующих мою реализацию новых плагинов или фильтров FluentD, относительно просто (вам понадобится некоторый опыт работы с Ruby 😆).

Вы можете найти драгоценный камень ключ-значение на Github и на моей веб-странице. Мы высоко ценим отзывы и идеи по улучшению фильтра FluentD.