Передача логов с ВМ в Yandex Cloud Logging
Обработчик логов Fluent Bit
Чтобы настроить передачу логов:
Перед началом работы
- Создайте сервисный аккаунт с ролью
logging.writer
на каталог. - Создайте ВМ из публичного образа Ubuntu 20.04. В блоке Доступ укажите сервисный аккаунт, который создали на предыдущем шаге.
- Подключитесь к ВМ по SSH.
- Установите на ВМ:
-
wget https://go.dev/dl/go1.17.6.linux-amd64.tar.gz tar -xzf go1.17.6.linux-amd64.tar.gz export PATH=$PWD/go/bin:$PATH
-
Git:
sudo apt install git
-
Создайте сервис systemd, генерирующий логи
-
Создайте директорию:
sudo mkdir /usr/local/bin/logtest sudo chown $USER /usr/local/bin/logtest cd /usr/local/bin/logtest
-
Создайте файл
logtest.py
:import logging import random import sys import time from systemdlogging.toolbox import check_for_systemd from systemdlogging.toolbox import SystemdFormatter from systemdlogging.toolbox import SystemdHandler # Следующие несколько строк можно заменить на вызов `systemdlogging.toolbox.init_systemd_logging` # Код приводится в целях демонстрации # Проверяем, доступен ли systemd systemd_ok = check_for_systemd() if systemd_ok: handler = SystemdHandler() # syslog_id: значение, которое будет использовано в поле SYSLOG_IDENTIFIER handler.syslog_id = '' handler.setFormatter(SystemdFormatter()) # Получаем экземпляр объекта логгера logger = logging.getLogger() logger.addHandler(handler) else: logger = logging.getLogger(__name__) # Логи выводятся в STDOUT handler = logging.StreamHandler(stream=sys.stdout) handler.setFormatter(logging.Formatter( '[%(levelname)s] %(code)d %(message)s' )) logger.addHandler(handler) # Настраиваем уровень логирования по умолчанию, опционально logger.setLevel(logging.DEBUG) # Генерируем URL-подобные значения PATHS = [ '/', '/admin', '/hello', '/docs', ] PARAMS = [ 'foo', 'bar', 'query', 'search', None ] def fake_url(): path = random.choice(PATHS) param = random.choice(PARAMS) if param: val = random.randint(0, 100) param += '=%s' % val code = random.choices([200, 400, 404, 500], weights=[10, 2, 2, 1])[0] return '?'.join(filter(None, [path, param])), code if __name__ == '__main__': while True: # Создаем пару — код и значение URL path, code = fake_url() # Если код 200, пишем в лог с уровнем Info # Cloud Logging смотрит на текстовое написание уровня логирования, поэтому в `context` передаем # дополнительное значение `SEVERITY` # Оно попадет в journald и сможет быть прочитано в плагине yc-logging if code == 200: logger.info( 'Path: %s', path, extra={"code": code, "context": {"SEVERITY": "info"}}, ) # Иначе с уровнем Error else: logger.error( 'Error: %s', path, extra={"code": code, "context": {"SEVERITY": "error"}}, ) # Ждем 1 секунду, чтобы не засорять журнал time.sleep(1)
-
Обновите версии установленных пакетов:
sudo apt-get update
-
Создайте виртуальную среду и установите необходимые зависимости:
sudo apt install python3-pip python3.8-venv
python3 -m venv venv source venv/bin/activate pip3 install systemd-logging
-
Создайте файл
logtest.sh
:#!/bin/bash SCRIPT_PATH=$(dirname "$(realpath "$0")") . "$SCRIPT_PATH/venv/bin/activate" python "$SCRIPT_PATH/logtest.py"
-
systemd
будет вызыватьlogtest.sh
для запуска сервиса, поэтому сделайте файл исполняемым:chmod +x logtest.sh
-
Создайте файл
logtest.service
:[Unit] Description=Sample to show logging from a Python application to systemd After=network.target [Service] Type=simple ExecStart=/usr/local/bin/logtest/logtest.sh Restart=on-abort [Install] WantedBy=multi-user.target
-
Создайте символическую ссылку для
logtest.service
:sudo ln -s "$(pwd)/logtest.service" /etc/systemd/system/logtest.service
-
Перезапустите
systemd
:sudo systemctl daemon-reload
-
Посмотрите статус сервиса
logtest.service
:systemctl status logtest.service
Результат:
● logtest.service - Sample to show logging from a Python application to systemd Loaded: loaded (/etc/systemd/system/logtest.service; linked; vendor preset: enabled) Active: inactive (dead)
-
Запустите сервис
logtest.service
:sudo systemctl start logtest.service
-
Снова посмотрите статус сервиса
logtest.service
, теперь он должен быть активен:systemctl status logtest.service
Результат:
● logtest.service - Sample to show logging from a Python application to systemd Loaded: loaded (/etc/systemd/system/logtest.service; linked; vendor preset: enabled) Active: active (running) since Wed 2022-02-02 18:49:03 UTC; 13h ago Main PID: 6550 (logtest.sh) Tasks: 2 (limit: 2311) Memory: 8.5M CGroup: /system.slice/logtest.service ├─6550 /bin/bash /usr/local/bin/logtest/logtest.sh └─6568 python /usr/local/bin/logtest/logtest.py
Установите и настройте Fluent Bit
-
Добавьте GPG-ключ, которым подписаны пакеты в репозитории Fluent Bit:
wget -qO - https://packages.fluentbit.io/fluentbit.key | sudo apt-key add -
-
Добавьте в файл
/etc/apt/sources.list
следующую строку:deb https://packages.fluentbit.io/ubuntu/focal focal main
-
Обновите версии установленных пакетов:
sudo apt-get update
-
Установите пакет
fluent-bit
:sudo apt-get install fluent-bit
-
Запустите сервис
fluent-bit
:sudo systemctl start fluent-bit
-
Проверьте статус сервиса
fluent-bit
, он должен быть активен:systemctl status fluent-bit
Результат:
● fluent-bit.service - Fluent Bit Loaded: loaded (/lib/systemd/system/fluent-bit.service; disabled; vendor preset: enabled) Active: active (running) since Tue 2024-04-30 09:00:58 UTC; 3h 35min ago Docs: https://docs.fluentbit.io/manual/ Main PID: 589764 (fluent-bit) Tasks: 9 (limit: 2219) Memory: 18.8M CPU: 2.543s CGroup: /system.slice/fluent-bit.service └─589764 /opt/fluent-bit/bin/fluent-bit -c //etc/fluent-bit/fluent-bit.conf
Подключите плагин
-
Клонируйте репозиторий с кодом плагина:
git clone https://github.com/yandex-cloud/fluent-bit-plugin-yandex.git
-
Запишите в переменные окружения версии пакетов:
cd fluent-bit-plugin-yandex/ export fluent_bit_version=3.0.3 export golang_version=1.22.2 export plugin_version=dev
Где:
fluent_bit_version
— версия пакетаfluent-bit
. Для проверки версии воспользуйтесь командой/opt/fluent-bit/bin/fluent-bit --version
.golang_version
— версия компилятора Go. Для проверки версии воспользуйтесь командойgo version
.
-
Выйдите из виртуального окружения Python и назначьте права на директорию с плагином:
deactivate
sudo chown -R $USER:$USER /fluent-bit-plugin-yandex
-
Скомпилируйте библиотеку
yc-logging.so
:CGO_ENABLED=1 go build -buildmode=c-shared \ -o ./yc-logging.so \ -ldflags "-X main.PluginVersion=${plugin_version}" \ -ldflags "-X main.FluentBitVersion=${fluent_bit_version}"
-
Скопируйте библиотеку
yc-logging.so
в директорию библиотекfluent-bit
:sudo cp yc-logging.so /usr/lib/fluent-bit/plugins/yc-logging.so
-
Добавьте в файл с настройками плагинов
/etc/fluent-bit/plugins.conf
путь до библиотекиyc-logging.so
:[PLUGINS] Path /usr/lib/fluent-bit/plugins/yc-logging.so
-
Добавьте в файл
/etc/fluent-bit/fluent-bit.conf
настройки сервисаfluent-bit
:[INPUT] Name systemd Tag host.* Systemd_Filter _SYSTEMD_UNIT=logtest.service [OUTPUT] Name yc-logging Match * resource_type logtest folder_id <идентификатор_каталога> message_key MESSAGE level_key SEVERITY default_level WARN authorization instance-service-account
Где:
folder_id
— идентификатор каталога, в лог-группу по умолчанию которого будут передаваться логи.authorization
— настройки авторизации. Укажитеinstance-service-account
, чтобы авторизоваться от имени сервисного аккаунта, который указали в блоке Доступ при создании ВМ.
-
Перезапустите сервис
fluent-bit
:sudo systemctl restart fluent-bit
Посмотрите логи
- В консоли управления
перейдите в каталог, который указали в настройках сервисаfluent-bit
. - Выберите сервис Cloud Logging.
- Нажмите на строку c лог-группой по умолчанию
default
. - Перейдите на вкладку Логи.
- На открывшейся странице отобразятся записи.
Если у вас еще нет интерфейса командной строки Yandex Cloud, установите и инициализируйте его.
По умолчанию используется каталог, указанный в профиле CLI. Вы можете указать другой каталог с помощью параметра --folder-name
или --folder-id
.
Чтобы посмотреть записи в лог-группе, выполните команду:
yc logging read --folder-id=<идентификатор_каталога>
Где --folder-id
— идентификатор каталога, который указан в настройках сервиса fluent-bit
.
Чтобы посмотреть записи в лог-группе, воспользуйтесь вызовом gRPC API LogReadingService/Read.
Удалите созданные ресурсы
Если созданные ресурсы вам больше не нужны, удалите их: