Логирование и аудит

Рейтинг: 68.5% · 14 голосов
Исчерпывающий курс по Tarantool 3.x: модель данных, движки memtx и vinyl, Lua и файберы, транзакции и MVCC, SQL, конфигурация (box.cfg и декларативная 3.x), репликация и Raft, шардирование vshard, эксплуатация, безопасность. 47 уроков со схемами.
Ответить
Аватара пользователя
denis_tnt
Сообщения: 47
Зарегистрирован: 11 май 2026, 05:31

Логирование и аудит

Сообщение denis_tnt »

Оглавление курса (47)
  1. Что такое Tarantool: in-memory СУБД и сервер приложений
  2. Архитектура изнутри: процесс, потоки, event-loop
  3. Установка и первый запуск: tt CLI, пакеты, Docker
  4. Интерактив: консоль, admin-консоль, первые команды
  5. Спейсы и кортежи: форматы, типы данных
  6. Типы индексов и их применимость
  7. Движки хранения: memtx vs vinyl
  8. DDL: схема, создание спейсов и индексов, миграции
  9. DML и выборки: insert/update/upsert, итераторы
  10. Персистентность: WAL, снапшоты, recovery
  11. Внутренности memtx: аллокаторы slab/arena, память
  12. Внутренности vinyl: LSM, компакция, тюнинг
  13. Lua и LuaJIT в Tarantool: box, модули, rocks
  14. Файберы: кооперативная многозадачность, каналы
  15. Транзакции: ACID, изоляция, MVCC
  16. Хранимые процедуры, модули, организация приложения
  17. net.box: удалённые вызовы, async
  18. Пулы соединений, балансировка, реконнект
  19. Ошибки и диагностика: box.error, pcall
  20. Типы и сериализация: MsgPack, decimal, datetime, uuid
  21. SQL в Tarantool: возможности и связь с box
  22. SQL: таблицы, JOIN, подзапросы, представления
  23. SQL: подготовленные выражения, транзакции, Lua-интероп
  24. Классическая конфигурация box.cfg (legacy 1.x/2.x)
  25. Декларативная конфигурация 3.x: config.yaml, иерархия
  26. Роли и приложения в 3.x
  27. Централизованная конфигурация: etcd / config storage
  28. tt CLI глубоко: разработка, сборка, запуск
  29. Cartridge (официальный legacy) и миграция на 3.x
  30. Репликация: replicaset, топологии
  31. Механика репликации: WAL-стриминг, vclock
  32. Синхронная репликация и выборы лидера (Raft)
  33. Жизненный цикл узла: bootstrap, join, rejoin
  34. vshard: router/storage, виртуальные бакеты
  35. Решардинг и rebalancing бакетов
  36. Запросы поверх шардов: map-reduce, crud
  37. Мониторинг: метрики, Prometheus, Grafana
  38. Логирование и аудит (вы здесь)
  39. Бэкапы и восстановление
  40. Безопасность: аутентификация, RBAC, TLS
  41. Производительность: профилирование, тюнинг
  42. Обновления: схема, rolling upgrade
  43. Деплой в продакшен: Docker, топология (официальные паттерны)
  44. Администрирование через официальный TCM (Tarantool Cluster Manager)
  45. Коннекторы: Python, Go, Java
  46. Ключевые модули (rocks): crud, metrics, queue, expirationd
  47. Capstone: шардированный отказоустойчивый кластер
Зачем нужен этот урок

Лог - это первое, куда смотрит инженер, когда инстанс ведёт себя не так. Аудит - это отдельный поток, который отвечает на вопрос "кто и что сделал с данными и правами". В этом уроке мы разбираем, как внутри Tarantool устроен конвейер от события до строки в файле: куда, в каком формате и с какой детальностью пишутся сообщения, как это настраивается в двух треках (классический box.cfg и декларативный config.yaml 3.x), и где проходит граница между обычным логом и аудитом (последний - компонент Enterprise Edition).

Механика: как событие превращается в строку

Внутри ядра есть один общий логгер (say-подсистема, написанная на C). Любое сообщение - и от самого ядра (репликация, WAL, чекпойнты), и от вашего Lua-кода через модуль log - проходит через одну воронку из трёх решений:
  • Уровень (log_level). У каждого сообщения есть severity. Логгер сравнивает его с порогом и отбрасывает всё, что ниже. Числовая шкала фиксирована: 0 fatal, 1 syserror, 2 error, 3 crit, 4 warn, 5 info, 6 verbose, 7 debug. Пишутся события с severity ВЫШЕ ИЛИ РАВНО порогу. По умолчанию порог 5 (info), то есть verbose и debug молчат.
  • Назначение (log_to / log). Поток направляется в одно из трёх мест: файл, syslog или внешняя программа через пайп. Выбор взаимоисключающий - один логгер пишет в одно место.
  • Формат (log_format). Строка форматируется либо как plain (человекочитаемая), либо как json (машиночитаемая, по одному JSON-объекту на строку - удобно для сборщиков типа ELK/Loki).
Разберём типичную plain-строку из реального лога:

Код: Выделить всё

2024-04-09 17:34:38.905 [49502] main/116/console/unix/:/tarantool I> Hello
       время           pid    поток/файбер/роль                  ^уровень  сообщение
Здесь I> - это severity info. У error будет E>, у warn W>, у crit C> и так далее. В json-формате те же поля становятся ключами (time, level, message, pid, cord_name, fiber_id, fiber_name), что снимает боль парсинга многострочных stacktrace.

Неблокирующая запись (log_nonblock). Тонкий, но важный момент внутренней механики. При log_nonblock=true запись в лог не блокирует файбер: если буфер занят, сообщение может быть ПОТЕРЯНО, зато инстанс не встаёт. Для файла по умолчанию false (надёжность важнее), для syslog и пайпа - true. Это объясняет классический сюрприз: "часть сообщений из-под нагрузки не доехала".

Per-module уровни (log_modules). Можно задать общий порог пониже, а для шумного модуля - повыше (или наоборот). Внутри это таблица "имя модуля -> уровень", которую логгер сверяет до общего порога.

Изображение
Конвейер логов и потока аудита

Ключевые команды и конфиг

Трек 1 - классический box.cfg (1.x/2.x, работает и в 3.x).

Код: Выделить всё

box.cfg{
    log              = 'file:/var/log/tarantool/instance.log',
    log_level        = 'verbose',   -- можно строкой или числом 6
    log_format       = 'json',
    log_nonblock     = false,
    log_modules      = { replication = 'debug', memtx = 'warn' },
}
-- меняем порог на лету, без рестарта:
box.cfg{ log_level = 'debug' }
Трек 2 - декларативный config.yaml (3.x). Те же ручки, но под секцией log:

Код: Выделить всё

log:
  to: file
  file: /var/log/tarantool/instance.log
  level: verbose
  format: json
  nonblock: false
  modules:
    replication: debug
# отправка в syslog вместо файла:
# log:
#   to: syslog
#   syslog:
#     server: 127.0.0.1:514
#     identity: tarantool
Пишем в лог из своего кода (модуль log):

Код: Выделить всё

local log = require('log')
log.info('user %d logged in', 42)   -- printf-стиль форматирования
log.warn('cache miss for key %q', k)
log.error({code = 500, msg = 'boom'})  -- таблица сериализуется в структуру
-- свой модуль с отдельным уровнем:
local mylog = require('log').new('billing')
mylog.verbose('charge started')
Ротация. Tarantool сам файлы не нарезает. Внешний logrotate перемещает файл, после чего инстансу нужно ПЕРЕОТКРЫТЬ дескриптор, иначе он продолжит писать в уже переименованный (или удалённый) файл:

Код: Выделить всё

# из Lua после ротации:
require('log').rotate()
# или через tt (вызывается из postrotate logrotate):
tt logrotate
Аудит (Enterprise Edition)

Аудит - это НЕ обычный лог. Это отдельный поток с собственным файлом, форматом и фильтром, заточенный под безопасность и комплаенс. Записываются не "репликация догоняет мастер", а события вроде: вход пользователя (auth_ok/auth_fail), создание/удаление пользователя, выдача и отзыв прав, создание/дроп спейса, по желанию - доступ к данным конкретных спейсов.

Код: Выделить всё

box.cfg{
    audit_log    = 'file:/var/log/tarantool/audit.log',
    audit_format = 'json',                 -- json | csv (по умолчанию)
    audit_filter = 'auth,user_create,user_drop,grant,revoke',
    audit_spaces = { 'bands' },            -- логировать доступ только к этим спейсам
    audit_nonblock = true,
}
audit_filter - это белый список групп событий (например all, audit, auth, priv, ddl, custom). Каждая запись аудита в JSON содержит type, description, time, кто инициатор (user), session/connection и затронутые объекты. Поскольку формат стабильный и машиночитаемый, аудит обычно стримят в SIEM.

Частые заблуждения и грабли
  • "Поставил log_level=debug, а debug не пишется." Проверьте, что не перебивает per-module уровень или TT_LOG_LEVEL из окружения. Переменные окружения и log.cfg() до box.cfg() имеют приоритет на раннем старте.
  • "Лог растёт, диск кончился, ротация не сработала." logrotate переименовал файл, но без log.rotate()/tt logrotate инстанс пишет в старый inode. Файл "исчез", а место не освободилось, пока дескриптор открыт.
  • "Часть сообщений теряется под нагрузкой." Это log_nonblock=true для syslog/пайпа. Для гарантий используйте файл с nonblock=false.
  • "Включу аудит в Community Edition." Модуль аудита есть только в Enterprise. В CE этих опций нет.
  • "Аудит = просто очень подробный лог." Нет, это раздельные конвейеры: разный файл, формат, фильтр и семантика. Смешивать их в один файл не нужно.
  • Пишут в лог в горячем цикле на уровне info. Для частых событий существует verbose - его можно держать выключенным в проде и включать точечно.
Правило большого пальца: в проде держите общий уровень info, формат json (для сборщиков), файл с nonblock=false, ротацию через logrotate + tt logrotate. Аудит - отдельным файлом с узким audit_filter, иначе он станет неотличим от обычного лога по объёму.
Мини-лаба

Задание: на тестовом инстансе переключите формат лога на JSON и проверьте, что severity действительно фильтрует.

Код: Выделить всё

-- 1. посмотрите текущий порог
box.cfg.log_level          --> 5 (info)
-- 2. включите json и поднимите детальность
box.cfg{ log_format = 'json', log_level = 'verbose' }
-- 3. сгенерируйте три сообщения разной важности
require('log').verbose('v-line')
require('log').info('i-line')
require('log').debug('d-line')   -- НЕ должно попасть в файл при verbose
-- 4. откройте лог-файл: найдите v-line и i-line в JSON, убедитесь что d-line нет
Ожидаемый результат: в файле видны строки уровней info и verbose как JSON-объекты с полем level, а debug-строка отсутствует - порог отсёк её.

Контрольные вопросы
  • Какому числовому уровню соответствует verbose и почему при log_level=5 он не пишется в лог?
  • Чем грозит log_nonblock=true и для каких назначений (file/syslog/pipe) он включён по умолчанию?
  • Почему после работы logrotate инстансу обязательно нужен log.rotate() или tt logrotate? Что произойдёт, если этого не сделать?
  • Назовите минимум три отличия потока аудита от обычного лога и объясните, почему их разносят по разным файлам.
👍2 ❤️3 🔥1 😄 🤔
Ответить
← Предыдущая глава
Мониторинг: метрики, Prometheus, Grafana
Следующая глава →
Бэкапы и восстановление

Все главы курса «Tarantool: in-memory СУБД и сервер приложений с нуля до продакшена»

Поделиться темой: ✈ Telegram VK
  • Похожие темы

Вернуться в «Tarantool: СУБД и сервер приложений»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 2 гостя