Перейти к содержанию

Логирование

Логирование встроено в ядро как обёртка над стандартным logging, плюс всегда включённый middleware, который замеряет запросы и маскирует чувствительные данные.

Что попадает в логи

Каждый запрос даёт строку вида:

[INFO]  POST /v1/user/role 201 3ms id=8f2c… payload={'name': 'Ada', 'password': '***'}
[ERROR] GET /v1/user/0 -> 500 5ms id=… payload=… <traceback>
  • метод, путь, статус, длительность и id запроса;
  • payload запроса с замаскированными чувствительными ключами (password, token, authorization, secret, api_key, …) до какой-либо записи — сравнение по подстроке, без учёта регистра и разделителей, так что old_password, X-Api-Key и refresh_token тоже маскируются, а не только точное имя поля;
  • при ошибке — полный трейсбэк.

Почему маскирование на уровне логгера

Логирующий middleware видит сырой входящий JSON — до любого шифрования или сохранения. Маскировать именно там — единственный способ надёжно не пустить секреты в логи. Шифрование данных в БД потоку логов не помогает.

ID запросов

Каждый запрос получает X-Request-ID (входящий учитывается), который возвращается в ответе и включается в каждую строку лога — так один запрос можно проследить из конца в конец. За прокси — пробрасывайте заголовок.

Цветной вывод в dev

Когда stderr — это TTY, префикс уровня подкрашивается для читаемости. При перенаправлении вывода (файлы, агрегаторы) автоматически используется обычный текст.

Использование логгера в своём коде

from endocore import get_logger
log = get_logger()          # настроенный логгер "endocore"

log.info("processed order %s", order_id)

Замаскировать структуру вручную:

from endocore.core.logging import mask
mask({"password": "x", "name": "Ada"})     # {"password": "***", "name": "Ada"}

Настройка уровней / хендлеров

get_logger() возвращает стандартный logging.Logger, так что настраивается как обычно:

import logging
logging.getLogger("endocore").setLevel(logging.WARNING)