Как настроить и использовать ведение журнала
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, использующий FileHandler Python для сохранения журналов уровня 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.
Чтобы управлять этим поведением, установите ключ propagation в отображениях, которые вы определяете:
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/5.0/howto/logging/