Найти в Дзене
Сергей Озеранский

Как писать логи в Python правильно (по-взрослому)

Логи - это не "давайте залогируем все".
К логам стоит относиться как к инженерной задаче: с целями, рисками, стоимостью и требованиями. Мы это уже поняли отсюда Главная цель логов - помочь разобраться, что произошло, а не просто оставить след в истории. Хотя аудит логи можно приравнять к следу в истории, но мы разберем в первую очередь инженерные логи. Почти всегда нужны структурированные логи. Хотя я с ходу не придумал когда они нужны не структурированные.
Не потому что JSON модный, а потому что: 1. Стандартный logging (stdlib)
Подходит, если: Минус - структурированность приходится продумывать и поддерживать самостоятельно. 2. structlog - мой любимчик 
Почему его часто выбирают: Есть еще loguru, но я его не использовал. Мне как правило хватает structlog. Лог-уровни - это контракт
DEBUG - временно и осознанно. Выключен в продакшене
INFO - важные бизнес-события
WARNING - деградация, аномалия, требует внимание разработчика, но не блокер работы сервиса
ERROR - ошибка операции
CRITICAL -
Оглавление

Логи - это не "давайте залогируем все".
К логам стоит относиться как к инженерной задаче: с целями, рисками, стоимостью и требованиями. Мы это уже поняли
отсюда

Главная цель логов - помочь разобраться, что произошло, а не просто оставить след в истории. Хотя аудит логи можно приравнять к следу в истории, но мы разберем в первую очередь инженерные логи.

Базовый принцип

Почти всегда нужны структурированные логи. Хотя я с ходу не придумал когда они нужны не структурированные.
Не потому что JSON модный, а потому что:

  • по логам должны уметь работать машины;
  • по ним нужно фильтровать, агрегировать, строить алерты;
  • хаотичный текст = боль для всех, кто работает с логами на любом уровне и деньги (и бывают очень не малые) для бизнеса. Поинтересуйтесь, кстати, у своих коллег сколько стоят логи в вашей компании в месяц. 

Подходы к логированию в Python

1. Стандартный logging (stdlib)
Подходит, если:

  • вы пишете библиотеку. Минимум зависимостей;
  • сложно, но можно расширять;
  • инфраструктура уже завязана на стандартный логгер (хотя с этого можно мигрировать при желании).

Минус - структурированность приходится продумывать и поддерживать самостоятельно.

2. structlog - мой любимчик 
Почему его часто выбирают:

  • -лог это событие + набор полей;
  • легко добавлять контекст (request_id, trace_id);
  • огромная и мощная поддержка стандартных и кастомных процессоров;
  • идеально ложится в JSON и observability-стек.

Есть еще loguru, но я его не использовал. Мне как правило хватает structlog.

Общие best practices

Лог-уровни - это контракт
DEBUG - временно и осознанно. Выключен в продакшене
INFO - важные бизнес-события
WARNING - деградация, аномалия, требует внимание разработчика, но не блокер работы сервиса
ERROR - ошибка операции
CRITICAL - проблема сервиса

Не логируйте в открытом виде чувствительные данные

  • персональные данные;
  • токены, ключи, пароли;
  • номера карт и т. д.

Только усеченные данные или агрегация.

Добавляйте корреляцию
Минимум:
- request_id;
- correlation_id (актуально для микросервисов);
- trace_id/span_id (если есть трейсинг);
Но важен баланс, так как лог не должен содержать весь енвайремент, но должен содержать то, что требуется для быстрой отладки.

Разделяйте назначение логов

  • observability-логи - для дебага и инцидентов;
  • audit/compliance-логи - для регуляторов и хранения годами.

Думайте о стоимости
Каждый лог - это:

  • ingest;
  • хранение;
  • запросы.

Если лог никто не смотрит - возможно, он не нужен.

Краткий вывод

Хорошие логи:

  • структурированные;
  • осмысленные;
  • безопасные;
  • с понятным сроком жизни;
  • написаны под конкретную цель.

Логирование - это часть архитектуры, а не побочный эффект разработки.

Больше постов у меня в Telegram-канале: «Сергей Озеранский».