Сбор логов с помощью FluentBit
В разделе представлена реализация интеграции между YDB и инструментом захвата логов FluentBit с целью сохранения данных логов в YDB для последующего просмотра или анализа.
Введение
FluentBit – инструмент, который может собирать текстовые данные, манипулировать ими (изменять, преобразовывать, объединять) и отправлять в различные хранилища для дальнейшей обработки. Для поставки логов в таблицы YDB с помощью FluentBit разработана библиотека-плагин. Исходный код библиотеки доступен здесь.
Чтобы развернуть схему доставки логов с помощью FluentBit с последующим сохранением их в YDB, необходимо:
- Создать таблицы YDB для хранения логов
- Развернуть FluentBit и библиотеку-плагин для поддержки YDB
- Сконфигурировать FluentBit для сбора и обработки логов в соответствии с документацией
- Настроить сохранение логов в таблицы YDB
Создание таблиц для хранения логов
Для сохранения логов необходимо создать таблицы в выбранной базе данных YDB. Структура создаваемых таблиц определяется набором полей конкретного лога, поставляемого с помощью FluentBit. Типичный набор полей включает в себя:
- метку времени;
- уровень критичности сообщения;
- имя хоста, с которого получено сообщение;
- наименование сервиса;
- текст сообщения либо его структурированные данные в формате JSON.
В таблицах YDB обязательно наличие первичного ключа, уникально идентифицирующего конкретную запись. Поскольку метка времени не обеспечивает уникальной идентификации записи лога, в состав хранимых полей обычно добавляют значение хеш-кода над данными сообщения, которое включают в состав первичного ключа.
Поддерживается хранение логов как в строковых, так и колоночных таблицах. Рекомендуется использование колоночных таблиц, как обеспечивающих более эффективное сканирование данных при выполнении запросов.
Пример команды создания строковой таблицы для хранения логов:
CREATE TABLE `fluent-bit/log` (
`timestamp` Timestamp NOT NULL,
`hostname` Text NOT NULL,
`input` Text NOT NULL,
`datahash` Uint64 NOT NULL,
`level` Text NULL,
`message` Text NULL,
`other` JsonDocument NULL,
PRIMARY KEY (
`datahash`, `timestamp`, `hostname`, `input`
)
);
Пример команды создания колоночной таблицы для хранения логов:
CREATE TABLE `fluent-bit/log` (
`timestamp` Timestamp NOT NULL,
`hostname` Text NOT NULL,
`input` Text NOT NULL,
`datahash` Uint64 NOT NULL,
`level` Text NULL,
`message` Text NULL,
`other` JsonDocument NULL,
PRIMARY KEY (
`timestamp`, `hostname`, `input`, `datahash`
)
) PARTITION BY HASH(`timestamp`, `hostname`, `input`)
WITH (STORE = COLUMN);
Команда создание колоночной таблицы отличается от команды создания строковой таблицы следующими деталями:
- указанием в двух последних строках колоночного режима хранения и отдельного ключа партиционирования;
- колонка
timestamp
указана первой в составе первичного ключа таблицы, что является оптимальным и рекомендованным для колоночных таблиц, и не рекомендовано для строчных таблиц. См. также рекомендации по выбору первичного ключа для колоночных таблиц и для строчных таблиц.
Опционально можно настроить TTL для строк таблицы, ограничив срок хранения и обеспечив автоматическое удаление устаревших данных. Для этого при создании таблицы в секции WITH
указываются настройки TTL, например TTL = Interval("P14D") ON timestamp
устанавливает срок хранения записей в 14 дней на основе значения поля timestamp
.
Развертывание FluentBit и настройка сбора логов
Развертывание FluentBit осуществляется в соответствии с собственной документацией.
Плагин для поддержки YDB в FluentBit доступен в репозитории вместе с инструкциями по сборке. Для установки в формате контейнера предусмотрен Docker-образ ghcr.io/ydb-platform/fluent-bit-ydb
.
Общая логика и порядок настройки процессов получения, обработки и поставки логов в среде FluentBit изложены в документации FluentBit.
Настройка записи логов в YDB
Перед использованием выходного плагина для YDB, его необходимо включить в настройках FluentBit. Перечень используемых плагинов FluentBit определяется в отдельном файле (например, plugins.conf
), путь к которому устанавливается параметром plugins_file
секции SERVICE
основного файла настроек FluentBit. Пример файла плагинов со ссылкой на библиотеку плагина для записи в YDB (путь к библиотеке в вашей системе может отличаться):
# plugins.conf
[PLUGINS]
Path /usr/lib/fluent-bit/out_ydb.so
Состав конфигурационных параметров, поддерживаемых выходным плагином YDB для FluentBit, приведен в таблице ниже.
Ключ | Описание |
---|---|
Name |
Тип плагина, константа ydb |
Match |
(опционально) Выражение для отбора тегов записей, направляемых в YDB |
ConnectionURL |
URL для подключения к БД, включая протокол, хост, номер порта и путь к базе данных (см. документацию) |
TablePath |
Путь к таблице, начиная от корня базы данных (пример: fluent-bit/log ) |
Columns |
JSON-структура, состоящая из пар имен колонок, и устанавливающая соответствие между исходными колонками записи и целевыми колонками таблицы. Может включать перечисленные далее служебные псевдо-колонки |
CredentialsAnonymous |
Устанавливается в значение 1 для использования анонимной аутентификации |
CredentialsToken |
Значение токена аутентификации, для использования аутентификации непосредственно по значению токена |
CredentialsYcMetadata |
Устанавливается в значение 1 для использования аутентификации через метаданные виртуальной машины |
CredentialsStatic |
Логин и пароль для использования статического режима аутентификации, указанные в формате Логин:Пароль@ |
CredentialsYcServiceAccountKeyFile |
Путь к файлу ключа сервисного аккаунта, для аутентификации по ключу сервисного аккаунта |
CredentialsYcServiceAccountKeyJson |
JSON-данные ключа сервисного аккаунта, для аутентификации по ключу сервисного аккаунта без указания имени файла (удобно в среде K8s) |
Certificates |
Путь к файлу с сертификатом CA, либо непосредственно содержимое сертификата CA |
LogLevel |
Уровень логирования для плагина, одно из значений disabled (по умолчанию), trace , debug , info , warn , error , fatal либо panic |
Для использования в карте сопоставления колонок (параметр Columns
), в дополнение к полям записи FluentBit, доступны следующие служебные псевдо-колонки:
.timestamp
- метка времени сообщения (обязательная).input
- имя входного потока сообщений (обязательная).hash
- uint64 хеш-код, вычисленный над всеми полями сообщения, кроме псевдо-колонок (опциональная).other
- документ JSON, содержащий все поля сообщения, которые не были явным образом сопоставлены с конкретной выходной колонкой (опциональная)
Пример значения параметра Columns
:
{".timestamp": "timestamp", ".input": "input", ".hash": "datahash", "log": "message", "level": "level", "host": "hostname", ".other": "other"}
Сбор логов в кластере Kubernetes
FluentBit очень часто используется для сбора логов в кластерах Kubernetes. Принципиальная схема доставки логов запущенных приложений в Kubernetes с помощью FluentBit с последующим сохранением их в YDB выглядит следующим образом:
На этой схеме:
-
Поды приложений пишут логи в stdout/stderr
-
Текст из stdout/stderr сохраняется в виде файлов на рабочих узлах Kubernetes
-
Под с FluentBit:
- Монтирует каталог с лог-файлами рабочего узла Kubernetes
- Вычитывает из лог-файлов содержимое
- Обогащает записи дополнительными метаданными
- Сохраняет записи в базу данных YDB
Таблица для хранения логов Kubernetes
Структура таблицы YDB для хранения логов Kubernetes:
CREATE TABLE `fluent-bit/log` (
`timestamp` Timestamp NOT NULL,
`file` Text NOT NULL,
`pipe` Text NOT NULL,
`message` Text NULL,
`datahash` Uint64 NOT NULL,
`message_parsed` JSON NULL,
`kubernetes` JSON NULL,
PRIMARY KEY (
`timestamp`, `file`, `datahash`
)
) PARTITION BY HASH(`timestamp`, `file`)
WITH (STORE = COLUMN, TTL = Interval("P14D") ON `timestamp`);
Предназначение колонок:
timestamp
– временная метка лога;file
– название источника, из которого прочитан лог. В случае Kubernetes это будет имя файла, на worker ноде, в который записываются логи определенного pod;pipe
– stdout или stderr поток, куда была осуществлена запись на уровне приложения;datahash
– хеш-код, вычисленный над записью лога;message
– текстовая часть записи лога;message_parsed
– структурированное представление записи лога, если его удалось разобрать из текстовой части с помощью настроенных парсеров FluentBit;kubernetes
– информация о pod, включая название, неймспейс и аннотации.
Опционально, можно установить TTL для строк таблицы, как показано в примере выше.
Конфигурация FluentBit
Перед развертыванием FluentBit в среде Kubernetes необходимо подготовить файл настроек (обычно values.yaml
), в котором указываются параметры сбора и обработки логов. В этом разделе представлены необходимые пояснения по заполнению этого файла с примерами.
Необходимо указать репозиторий и версию образа контейнера FluentBit:
image:
repository: ghcr.io/ydb-platform/fluent-bit-ydb
tag: latest
В данном образе, по сравнению со стандартным, добавлена библиотека-плагин для поддержки YDB.
В следующих строках определены правила монтирования папок с логами в поды FluentBit:
volumeMounts:
- name: config
mountPath: /fluent-bit/etc/conf
daemonSetVolumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibcontainers
hostPath:
path: /var/lib/containerd/containers
- name: etcmachineid
hostPath:
path: /etc/machine-id
type: File
daemonSetVolumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibcontainers
mountPath: /var/lib/containerd/containers
readOnly: true
- name: etcmachineid
mountPath: /etc/machine-id
readOnly: true
Также необходимо переопределить команду и аргументы запуска FluentBit:
command:
- /fluent-bit/bin/fluent-bit
args:
- --workdir=/fluent-bit/etc
- --plugin=/fluent-bit/lib/out_ydb.so
- --config=/fluent-bit/etc/conf/fluent-bit.conf
Требуется настроить пайплайн сбора, преобразования и доставки логов:
config:
inputs: |
[INPUT]
Name tail
Path /var/log/containers/*.log
multiline.parser cri
Tag kube.*
Mem_Buf_Limit 5MB
Skip_Long_Lines On
filters: |
[FILTER]
Name kubernetes
Match kube.*
Keep_Log On
Merge_Log On
Merge_Log_Key log_parsed
K8S-Logging.Parser On
K8S-Logging.Exclude On
[FILTER]
Name modify
Match kube.*
Remove time
Remove _p
outputs: |
[OUTPUT]
Name ydb
Match kube.*
TablePath fluent-bit/log
Columns {".timestamp":"timestamp",".input":"file",".hash":"datahash","log":"message","log_parsed":"message_structured","stream":"pipe","kubernetes":"metadata"}
ConnectionURL ${OUTPUT_YDB_CONNECTION_URL}
CredentialsToken ${OUTPUT_YDB_CREDENTIALS_TOKEN}
Описание конфигурационных блоков:
inputs
- в этом блоке указываются откуда считывать и как разбирать логи. В данном случае, будет осуществляться чтение файликов*.log
из папки/var/log/containers/
, которая была смонтирована с хостаfilters
- в этом блоке указывается как будет осуществляться обработка логов. В данном случае: для каждого лога будут найдены соответствующие метаданные (в помощью kubernetes фильтра), а также, вырезаны неиспользуемые поля (_p, time)outputs
- в этом блоке указывается, куда будут отгружены логи. В данном случае в таблицуfluent-bit/log
в базе данных YDB. Параметры подключения к базе данных (в данном случаеConnectionURL
иCredentialsToken
) задаются с помощью переменных окружения –OUTPUT_YDB_CONNECTION_URL
,OUTPUT_YDB_CREDENTIALS_TOKEN
. При необходимости настройки аутентификации и состав используемых переменных окружения корректируются в зависимости от настроек используемого кластера YDB.
Переменные окружения определяются следующим образом:
env:
- name: OUTPUT_YDB_CONNECTION_URL
value: grpc://ydb-endpoint:2135/path/to/database
- name: OUTPUT_YDB_CREDENTIALS_TOKEN
valueFrom:
secretKeyRef:
key: token
name: fluent-bit-ydb-plugin-token
Данные аутентификации необходимо сохранить в конфигурации кластера Kubernetes в виде секрета. Пример команды для создания секрета:
kubectl create secret -n ydb-fluent-bit-integration generic fluent-bit-ydb-plugin-token --from-literal=token=<YDB TOKEN>
Развертывание FluentBit в кластере Kubernetes
HELM – это инструмент пакетирования и установки приложений в кластере Kubernetes. Для развертывания FluentBit необходимо добавить репозиторий с соответствующим чартом (сценарием установки) с помощью команды:
helm repo add fluent https://fluent.github.io/helm-charts
После этого установка FluentBit в кластер Kubernetes выполняется с помощью следующей команды:
helm upgrade --install fluent-bit fluent/fluent-bit \
--version 0.37.1 \
--namespace ydb-fluent-bit-integration \
--create-namespace \
--values values.yaml
В команде выше в аргументе --values
указывается ранее подготовленный файл с настройками FluentBit.
Проверка установки
Проверяем что FluentBit запустился, читая его логи (должны отсутствовать записи уровня [error]
):
kubectl logs -n ydb-fluent-bit-integration -l app.kubernetes.io/instance=fluent-bit
Проверяем, что записи в таблице YDB есть (появятся спустя примерно несколько минут после запуска FluentBit):
SELECT * FROM `fluent-bit/log` LIMIT 10 ORDER BY `timestamp` DESC
Очистка ресурсов
Для удаления FluentBit достаточно удалить Kubernetes namespace, в который была выполнена установка:
kubectl delete namespace ydb-fluent-bit-integration
Далее можно удалить таблицу с логами в базе данных YDB:
DROP TABLE `fluent-bit/log`