Как настроить и использовать логирование
Django предоставляет работающую конфигурацию логирования по умолчанию, которую легко расширить.
Сделайте базовый вызов логирования
Чтобы отправить сообщение в журнал из кода, добавьте в него вызов логирования.
Не поддавайтесь искушению использовать вызовы логирования в settings.py.
Способ настройки логирования Django в рамках функции setup() означает, что вызовы логирования, размещённые в settings.py, могут работать не так, как ожидается, поскольку на этом этапе логирование ещё не настроено. Чтобы изучить логирование, используйте функцию-представление, как показано в примере ниже.
Сначала импортируйте библиотеку логирования Python, а затем получите экземпляр логгера с помощью logging.getLogger(). Передайте методу getLogger() имя, которое позволит идентифицировать его и создаваемые им записи. Хороший вариант — использовать __name__ (подробнее об этом см. ниже в разделе Используйте пространства имён логгеров), чтобы получить имя текущего модуля Python в виде пути с точками:
import logging logger = logging.getLogger(__name__)
Обычно это объявление размещают на уровне модуля.
Затем отправьте запись в логгер из функции, например из представления:
def some_view(request):
...
if some_risky_state:
logger.warning("Platform is running at risk")
При выполнении этого кода логгеру будет отправлен LogRecord с этим сообщением. Если вы используете конфигурацию логирования Django по умолчанию, сообщение появится в консоли.
Уровень WARNING, использованный в примере выше, — один из нескольких уровней важности сообщений журнала: DEBUG, INFO, WARNING, ERROR, CRITICAL. Например, можно написать так:
logger.critical("Payment system is not responding")
Важно
По умолчанию записи с уровнем ниже WARNING не отображаются в консоли. Для изменения этого поведения потребуется дополнительная конфигурация.
Настройте конфигурацию логирования
Хотя конфигурация логирования Django работает сразу после установки, с помощью дополнительной настройки можно точно контролировать, куда отправляются журналы: в файлы журналов, внешние службы, по электронной почте и т. д.
Можно настроить:
- сопоставления логгеров, определяющие, какие записи отправляются каким обработчикам
- обработчики, определяющие, что делать с полученными записями
- фильтры, позволяющие дополнительно контролировать передачу записей и даже изменять их на месте
- форматировщики, преобразующие объекты
LogRecordв строку или другую форму, удобную для восприятия людьми или обработки другой системой
Настроить логирование можно разными способами. В Django чаще всего используется параметр LOGGING. Этот параметр использует формат dictConfig и расширяет конфигурацию логирования по умолчанию.
Объяснение того, как пользовательские настройки объединяются со стандартными настройками Django, см. в разделе Настройка логирования.
Подробнее о других способах настройки логирования см. в Python logging documentation. Для простоты в этой документации рассматривается только настройка с помощью параметра LOGGING.
Базовая настройка логирования
При настройке логирования имеет смысл
Создать словарь LOGGING
В файле settings.py:
LOGGING = {
"version": 1, # the dictConfig format version
"disable_existing_loggers": False, # retain the default loggers
}
Почти всегда имеет смысл сохранить и расширить конфигурацию логирования по умолчанию, установив disable_existing_loggers в значение False.
Настроить обработчик
В этом примере настраивается один обработчик с именем file, который использует класс Python FileHandler, чтобы сохранять в файл general.log (в корневом каталоге проекта) журналы уровня DEBUG и выше:
LOGGING = {
# ...
"handlers": {
"file": {
"class": "logging.FileHandler",
"filename": "general.log",
},
},
}
Для разных классов обработчиков требуются разные параметры конфигурации. Сведения о доступных классах обработчиков см. в описании AdminEmailHandler, предоставляемого Django, и различных handler classes, предоставляемых Python.
Уровни логирования также можно задавать для обработчиков (по умолчанию они принимают сообщения журнала любого уровня). Если использовать пример выше и добавить:
{
"class": "logging.FileHandler",
"filename": "general.log",
"level": "DEBUG",
}
то будет определена конфигурация обработчика, принимающего только записи уровня DEBUG и выше.
Настроить сопоставление логгера
Чтобы отправлять записи этому обработчику, настройте сопоставление логгера, использующее его, например:
LOGGING = {
# ...
"loggers": {
"": {
"level": "DEBUG",
"handlers": ["file"],
},
},
}
Имя сопоставления определяет, какие записи журнала оно будет обрабатывать. Эта конфигурация ('') не имеет имени. Это означает, что она будет обрабатывать записи всех логгеров (о том, как использовать имя сопоставления для определения логгеров, записи которых оно будет обрабатывать, см. ниже в разделе Используйте пространства имён логгеров).
Оно будет передавать обработчику с именем file сообщения уровня DEBUG и выше.
Обратите внимание, что логгер может передавать сообщения нескольким обработчикам, поэтому связь между логгерами и обработчиками является «многие ко многим».
Если выполнить в коде:
logger.debug("Attempting to connect to API")
это сообщение появится в файле general.log в корневом каталоге проекта.
Настроить форматировщик
По умолчанию конечный вывод журнала содержит только текст сообщения из каждого log
record. Если нужно включить дополнительные данные, используйте форматировщик. Сначала задайте имена и определите форматировщики — в этом примере определяются форматировщики с именами verbose и simple:
LOGGING = {
# ...
"formatters": {
"verbose": {
"format": "{name} {levelname} {asctime} {module} {process:d} {thread:d} {message}",
"style": "{",
},
"simple": {
"format": "{levelname} {message}",
"style": "{",
},
},
}
Ключевое слово style позволяет указать { для форматирования с помощью str.format() или $ для форматирования с помощью string.Template; по умолчанию используется $.
Доступные для включения атрибуты LogRecord перечислены в разделе Атрибуты LogRecord.
Чтобы применить форматировщик к обработчику, добавьте в словарь обработчика запись formatter со ссылкой на форматировщик по имени, например:
"handlers": {
"file": {
"class": "logging.FileHandler",
"filename": "general.log",
"formatter": "verbose",
},
}
Используйте пространства имён логгеров
Конфигурация логирования без имени '' перехватывает журналы любого приложения Python. Именованная конфигурация логирования перехватывает журналы только от логгеров с соответствующими именами.
Пространство имён экземпляра логгера задаётся с помощью getLogger(). Например, в views.py из my_app:
logger = logging.getLogger(__name__)
создаст логгер в пространстве имён my_app.views. __name__ позволяет автоматически упорядочивать сообщения журнала по их происхождению в приложениях вашего проекта. Это также гарантирует, что имена не будут конфликтовать.
Сопоставление логгера с именем my_app.views перехватит записи от этого логгера:
LOGGING = {
# ...
"loggers": {
"my_app.views": {...},
},
}
Сопоставление логгера с именем my_app будет менее строгим и перехватит записи от логгеров в любом месте пространства имён my_app (включая my_app.views, my_app.utils и т. д.):
LOGGING = {
# ...
"loggers": {
"my_app": {...},
},
}
Также можно явно задать пространство имён логгера:
logger = logging.getLogger("project.payment")
и соответствующим образом настроить сопоставления логгеров.
Использование иерархии логгеров и распространения записей
Имена логгеров образуют иерархию. my_app является родительским для my_app.views, который, в свою очередь, является родительским для my_app.views.private. Если не указано иное, сопоставления логгеров передают обработанные ими записи родительским логгерам — запись от логгера в пространстве имён my_app.views.private будет обработана сопоставлениями как для my_app, так и для my_app.views.
Чтобы управлять этим поведением, задайте ключ распространения в определяемых вами сопоставлениях:
LOGGING = {
# ...
"loggers": {
"my_app": {
# ...
},
"my_app.views": {
# ...
},
"my_app.views.private": {
# ...
"propagate": False,
},
},
}
По умолчанию propagate имеет значение True. В этом примере журналы из my_app.views.private не будут обрабатываться родительским логгером, а журналы из my_app.views будут.
Настройте адаптивное логирование
Логирование наиболее полезно, когда содержит как можно больше информации, но не лишней — необходимый объём зависит от выполняемой задачи. При отладке требуется такой уровень подробности, который был бы чрезмерным и бесполезным, если бы с ним приходилось работать в рабочей среде.
Логирование можно настроить так, чтобы получать нужный уровень подробности именно тогда, когда он нужен. Вместо того чтобы вручную менять конфигурацию, лучше автоматически применять её в зависимости от среды.
Например, можно задать соответствующее значение переменной окружения DJANGO_LOG_LEVEL в средах разработки и подготовки, а затем использовать её в сопоставлении логгера, например так:
"level": os.getenv("DJANGO_LOG_LEVEL", "WARNING")
— таким образом, если в среде не указан более низкий уровень логирования, эта конфигурация будет передавать обработчику только записи уровня WARNING и выше.
Аналогичным образом можно управлять и другими параметрами конфигурации (например, параметром level или formatter обработчиков).
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/6.0/howto/logging/