Логирование¶
Логирование встроено в ядро как обёртка над стандартным 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, так что настраивается
как обычно: