Как настроить и использовать журналирование
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 для сохранения журналов уровня DEBUG и выше в файл general.log (в корне проекта):
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'],
},
},
}
Имя сопоставления определяет, какие записи журнала будут обрабатываться. Эта конфигурация ('') является безымянной. Это означает, что она будет обрабатывать записи от всех регистраторов (см. Использование именования регистраторов ниже о том, как использовать имя сопоставления для определения регистраторов, для которых она будет обрабатывать записи).
Она будет пересылать сообщения уровней DEBUG и выше обработчику с именем file.
Обратите внимание, что один регистратор может пересылать сообщения в несколько обработчиков, поэтому отношение между регистраторами и обработчиками является множественным.
Если вы выполните:
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/4.0/howto/logging/