Логирование
quite-admin использует настройки логирования приложения. Библиотека не вызывает
basicConfig(), dictConfig() или structlog.configure(), не задаёт уровни, не добавляет
console/file handlers и не перенастраивает логгеры приложения/root. По умолчанию используется
logging.getLogger("quite_admin") с NullHandler и включённым propagation.
Выбор логгера
import logging
from quite_admin import Admin
admin = Admin(
auth=auth_backend,
secret_key=session_secret,
logger=logging.getLogger("quite_admin"), # Необязательно: это значение по умолчанию
)
Можно передать stdlib logger, LoggerAdapter, picologging или структурированный логгер.
LoggerProtocol описывает методы debug, info, warning; они могут возвращать
None либо awaitable. Выбранный логгер также доступен как admin.logger.
| Режим | Форма вызова | Где находятся поля |
|---|---|---|
log_structured=False (по умолчанию) |
logger.info(event, extra={"quite_admin": fields}) |
LogRecord.quite_admin в stdlib logging; ограничение picologging описано ниже |
log_structured=True |
logger.info(event, **fields) |
В полях структурированного события |
Для структурированного режима нужно явно передать логгер. Stdlib Logger и
LoggerAdapter с log_structured=True отклоняются при инициализации.
Контекст LoggerAdapter сохраняется вместе с namespace quite_admin, в том числе
на версиях Python, где адаптер по умолчанию отбрасывает переданный в вызове extra.
FastAPI и Uvicorn
FastAPI использует Python logging, а серверные, access-логи и ошибки настраиваются
в Uvicorn. Чтобы отправить события библиотеки
в обычный formatter Uvicorn и сохранить его существующие логгеры:
from copy import deepcopy
import uvicorn
from uvicorn.config import LOGGING_CONFIG
log_config = deepcopy(LOGGING_CONFIG)
log_config["loggers"]["quite_admin"] = {
"handlers": ["default"],
"level": "INFO",
"propagate": False,
}
if __name__ == "__main__":
uvicorn.run("myapp:app", log_config=log_config)
Обычный текстовый formatter показывает имя события. Для JSON с метаданными используйте
свой formatter или structlog.stdlib.ProcessorFormatter с structlog.stdlib.ExtraAdder,
который добавит LogRecord.quite_admin в структурированный вывод.
Не направляйте события библиотеки в uvicorn.access: его formatter требует поля access-record Uvicorn.
Вместо Python-конфигурации можно передать Uvicorn параметр --log-config.
Litestar LoggingConfig и очереди
Актуальный стабильный Litestar 2 предоставляет LoggingConfig, queue-based handler,
picologging и StructlogPlugin; см. документацию Litestar.
Передавайте логгер приложения, чтобы админка использовала тот же backend:
from litestar import Litestar
from litestar.logging import LoggingConfig
from litestar.middleware.logging import LoggingMiddlewareConfig
from quite_admin import Admin
app = Litestar(
logging_config=LoggingConfig(logging_module="logging", log_exceptions="always"),
middleware=[LoggingMiddlewareConfig(
request_log_fields=("method", "path"),
response_log_fields=("status_code",),
).middleware],
)
admin = Admin(
auth=auth_backend,
secret_key=session_secret,
logger=app.get_logger("quite_admin"),
)
admin.mount_litestar(app)
Queue listener, formatter и уровни остаются под управлением приложения.
При замене console sink на Python 3.11 также задайте для queue_listener
class="litestar.logging.standard.QueueListenerHandler" и
handlers=["cfg://handlers.console"]. Иначе этот обработчик создаст собственный sink в stderr.
На Python 3.12+ используется конфигурация stdlib-очереди, которая по умолчанию ссылается на console.
Для picologging задайте logging_module="picologging" и так же передайте app.get_logger(...).
Если явно не выбрать модуль, Litestar 2 использует picologging, когда он установлен.
Обычный logging.getLogger() не возвращает picologging logger.
Проверенный picologging 0.9.3 принимает, но игнорирует extra: имена событий и уровни
работают, однако LogRecord.quite_admin недоступен. Не используйте %(quite_admin)s в его formatter.
Если нужны метаданные, выберите logging_module="logging", как в примере выше, либо StructlogPlugin.
quite-admin не изменяет picologging и фильтры приложения ради обхода этого ограничения backend.
StructlogPlugin и структурированные события
Установите structlog в приложение и используйте плагин Litestar:
from litestar import Litestar
from litestar.middleware.logging import LoggingMiddlewareConfig
from litestar.plugins.structlog import StructlogConfig, StructlogPlugin
from quite_admin import Admin
plugin = StructlogPlugin(StructlogConfig(
middleware_logging_config=LoggingMiddlewareConfig(
request_log_fields=("method", "path"),
response_log_fields=("status_code",),
),
))
app = Litestar(plugins=[plugin])
admin = Admin(
auth=auth_backend,
secret_key=session_secret,
logger=app.get_logger("quite_admin").bind(component="admin"),
log_structured=True,
)
admin.mount_litestar(app)
В FastAPI после настройки structlog в приложении передайте structlog.get_logger("quite_admin")
с log_structured=True. Поддерживается и логгер с настроенным
structlog.stdlib.ProcessorFormatter; конфигурация renderer остаётся за приложением.
Добавьте structlog.contextvars.merge_contextvars в цепочку processors для request ID
и tracing context. Админка не привязывает и не очищает контекст приложения.
ASGI-граница сохраняет контекст запроса, а AnyIO переносит его в worker threads
синхронных context callbacks собственных страниц.
Loguru использует ту же форму вызова со структурированными полями:
from loguru import logger
admin = Admin(
auth=auth_backend,
secret_key=session_secret,
logger=logger.bind(component="admin"),
log_structured=True,
)
Поля доступны в record["extra"] Loguru. Sinks и очереди настраивает приложение.
structlog, Loguru и picologging не становятся обязательными зависимостями quite-admin.
Middleware логирования запросов
Монтирование совместимо с чтением тела в LoggingMiddleware Litestar: поддержаны
кешированное тело, потоковые формы и лимит админки в 1 MiB.
Наш ASGI-handler локально предоставляет метод получения лимита для Litestar 2
и переводит публичный Request.stream() в ASGI receive-сообщения. Отдельный receive guard
этого mount считает байты до middleware, в том числе при повторных попытках чтения парсером.
Классы фреймворка глобально не изменяются.
По умолчанию middleware Litestar логирует тела и cookies. Для админки используйте
ограниченный набор полей из примеров выше: login-body содержит пароль и CSRF,
ответы — session cookies и значения записей. Админка не может удалить данные,
которые внешнее middleware приложения самостоятельно записывает в логи.
События библиотеки
| Событие | Уровень | Поля |
|---|---|---|
quite_admin.login_succeeded |
INFO | status_code |
quite_admin.login_failed |
WARNING | status_code |
quite_admin.login_throttled |
WARNING | status_code |
quite_admin.logout |
INFO | status_code |
quite_admin.record_created |
INFO | collection, status_code |
quite_admin.record_updated |
INFO | collection, status_code |
quite_admin.record_deleted |
INFO | collection, status_code |
quite_admin.record_conflict |
WARNING | collection, status_code |
quite_admin.validation_failed |
DEBUG | collection, status_code |
quite_admin.permission_denied |
WARNING | collection, operation, status_code |
quite_admin.csrf_rejected |
WARNING | status_code |
Метаданные, которые добавляет библиотека, не содержат credentials, identity, токены, cookies, headers, URL,
query string, ключи записей, значения полей и исходные сообщения исключений.
Дополнительный контекст, привязанный приложением к логгеру, остаётся под вашим управлением.
События изменения данных записываются после успешного commit адаптера.
Это диагностические события, а не надёжное хранилище audit log.
Отдельная история действий сохраняет активность авторизованных пользователей;
обычные логи по-прежнему не дополняются identity и данными записей.
Админка не добавляет собственный access-log на каждый запрос и не перехватывает
неожиданные исключения ради повторного логирования: они доходят до error pipeline
приложения/сервера. Если sink или processor падает, библиотека пытается записать
quite_admin.logging_failed через stdlib logger только с event_name и error_type.
Сбой logging sink не меняет HTTP-результат и не откатывает уже сохранённую запись.
Проверяемая совместимость
Тесты покрывают formatter Uvicorn, LoggingConfig и настоящий queue listener Litestar,
LoggerAdapter, JSON через StructlogPlugin, Loguru, перенос контекста, body-reading
middleware, исключение чувствительных данных и отказ sink.
Опциональный picologging проверяется отдельным CI job на Python 3.12 через
uv sync --locked --group logging-check. Основная матрица Python 3.11–3.15 не требует
picologging и не гарантирует поддержку его C-расширения для каждой комбинации Python и ОС.