Извлекайте пары ключ-значение из строк журнала с помощью парсера 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.