Логи - способ узнать, что делает Django-приложение в продакшене. В уроке соберём практичную схему: словарь LOGGING, логи запросов с id, структурированный JSON и отдельную конфигурацию для каждого окружения.

От print к logging

У print нет уровня, времени, источника и трассировки. Стандартный модуль logging даёт уровни, именованные логгеры, несколько назначений и форматов. Сам Django пишет через него (django.request, django.db.backends).

Как путешествует запись лога
Как путешествует запись лога
БлокРоль
LoggerОбъект, который вы вызываете; имя - getLogger(__name__)
HandlerКуда уходит запись: консоль, файл, почта, коллектор
FormatterКак она выглядит: текст или JSON
FilterОтбрасывает записи или добавляет поля, например request_id

Логирование в коде

python
import logging
import sys

logging.basicConfig(
    stream=sys.stdout,
    level=logging.INFO,
    format='%(levelname)s %(name)s %(message)s',
)
log = logging.getLogger('shop.orders')
log.debug('hidden')
log.info('order %s created', 42)
log.warning('stock low: %d left', 3)

Вывод:

text
INFO shop.orders order 42 created
WARNING shop.orders stock low: 3 left

Строка DEBUG отброшена, потому что порог - INFO. Значения передавайте аргументами (%s), а не через f-строку.

УровеньКогда
DEBUGДетали, только в разработке
INFOОбычные события: заказ создан
WARNINGНеожиданно, но работает
ERRORОперация не удалась
CRITICALСистема не работает
python
# shop/services.py
import logging

logger = logging.getLogger(__name__)   # -> 'shop.services'

def pay(order_id):
    logger.info('paying order %s', order_id)
    try:
        charge(order_id)
    except TimeoutError:
        logger.exception('payment gateway timeout, order %s', order_id)
        raise