• 3.1
  • 3.2
  • 5.0
  • Версия документации: 6.1

Как настроить и вести логи

Django предоставляет рабочую конфигурацию ведения журнала по умолчанию, которую легко расширить.

Сделайте простую запись лога

Чтобы отправить сообщение журнала из вашего кода, нужно вызвать в нем метод лога.

Не вызывайте методы для записи логов в settings.py.

То, как логгирование Django настроено как часть функции setup(), означает, что вызовы логгирования, размещенные в settings.py, могут работать не так, как ожидается, поскольку логгирование не будет настроено на этом этапе. Чтобы изучить логгирование, используйте функцию представления, как предложено в примере ниже.

First, import the Python logging library, and then obtain a logger instance with logging.getLogger(). Provide the getLogger() method with a name to identify it and the records it emits. A good option is to use __name__ (see Использовать пространство имен логгера below for more on this) which will provide the name of the current Python module as a dotted path:

import logging

logger = logging.getLogger(__name__)

Хорошей практикой является выполнение этого объявления на уровне модуля.

А затем в функции, например в представлении, отправить запись в логгер:

def some_view(request):
    ...
    if some_risky_state:
        logger.warning("Platform is running at risk")

When this code is executed, a LogRecord containing that message will be sent to the logger. If you’re using Django’s default logging configuration, the message will appear in the console.

Уровень WARNING, используемый в примере выше, является одним из нескольких уровней ведения логов: DEBUG, INFO, WARNING, ERROR, CRITICAL. Таким образом, другой пример может быть:

logger.critical("Payment system is not responding")

Важно

Записи с уровнем ниже WARNING не будут отображаться в консоли по умолчанию. Изменение этого поведения требует дополнительной настройки.

Настройте конфигурацию ведения журнала

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

Вы можете настроить:

  • сопоставления логгеров, чтобы определить, какие записи отправляются каким обработчикам

  • обработчики, чтобы определить, что они делают с полученными записями

  • фильтры, чтобы обеспечить дополнительный контроль над передачей записей, и даже изменять записи на месте

  • форматеры, для преобразования объектов LogRecord в строку или другую форму для использования людьми или другой системой

Существуют различные способы настройки ведения логов. В Django чаще всего используется параметр LOGGING. Этот параметр использует формат dictConfig и расширяет конфигурацию ведения логов по умолчанию.

См. Настройка логгирования для объяснения того, как ваши пользовательские настройки объединяются с настройками Django по умолчанию.

См. Документацию по ведению логов в Python, чтобы узнать о других способах настройки ведения логов. Для простоты, эта документация будет рассматривать только настройку с помощью параметра LOGGING.

Базовая конфигурация ведения логов

When configuring logging, it makes sense to

Создать словарь 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",
        },
    },
}

Different handler classes take different configuration options. For more information on available handler classes, see the AdminEmailHandler provided by Django and the various handler classes provided by 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-attributes для атрибутов LogRecord, которые можно включить.

Чтобы применить форматер к обработчику, добавьте запись formatter в словарь обработчика, ссылаясь на форматер по имени, например:

"handlers": {
    "file": {
        "class": "logging.FileHandler",
        "filename": "general.log",
        "formatter": "verbose",
    },
}

Использовать пространство имен логгера

Безымянная конфигурация '' захватывает логи из любого приложения Python. Конфигурация с именем будет захватывать журналы только из логгеров с совпадающими именами.

The namespace of a logger instance is defined using getLogger(). For example in views.py of my_app:

logger = logging.getLogger(__name__)

создаст логгер в пространстве имен my_app.views. __name__ позволяет вам автоматически организовывать сообщения журнала в соответствии с их происхождением в приложениях вашего проекта. Это также гарантирует, что вы не будете сталкиваться с конфликтами имен.

Отображение логгера с именем my_app.views будет захватывать записи из этого логгера:

LOGGING = {
    # ...
    "loggers": {
        "my_app.views": {...},
    },
}

Отображение логгера с именем my_app будет захватывать записи из логгеров из любого места в пространстве имен my_app (включая my_app., 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) можно управлять аналогичным образом.

Back to Top