Короткий ответ
Логируют структурированные события с явным списком полей, а не произвольные объекты целиком, применяют маскирование известных чувствительных полей (пароль, токен, номер карты) на уровне логирующего слоя, и исключают из логов сырые тела запросов с персональными данными или маскируют идентифицирующую часть.
Как это работает подробнее
В логирующий pipeline добавляют фильтр или процессор, который проходит по словарю логируемых полей и заменяет значения по списку ключей-паттернов (password, token, authorization, card_number) на маску вроде [REDACTED], прежде чем запись попадёт в обработчик вывода.
Пример кода
example.py
import logging
SENSITIVE_KEYS = {"password", "token", "authorization", "card_number"}
class MaskSensitiveFilter(logging.Filter):
def filter(self, record):
if isinstance(record.args, dict):
record.args = {
k: "***" if k.lower() in SENSITIVE_KEYS else v
for k, v in record.args.items()
}
return True
logger.addFilter(MaskSensitiveFilter())Что использовать на практике
- Практика. Удобно логировать структурированные события (structlog, python-json-logger) с заранее определённым набором полей вместо logger.info(str(request_object)), что снижает риск случайно залогировать весь объект запроса целиком вместе с заголовком Authorization; для персональных данных email/телефон можно частично маскировать.
Подводные камни
- Риск. Логируют весь объект исключения вместе с контекстом запроса «для отладки», случайно попадая заголовки с токеном авторизации в текст лога; включают debug-режим фреймворка в production, при котором трассировки ошибок могут содержать значения переменных окружения на странице ошибки.