Spec-Zone.ru › Django 5.1

Ведение журнала

См. также

  • Как настроить и использовать ведение журнала
  • Справочник по ведению журнала Django

Python-программисты часто используют print() в своём коде в качестве быстрого и удобного инструмента отладки. Использование системы ведения журнала — это лишь немного больше усилий, но она гораздо элегантнее и гибче. Помимо полезности для отладки, ведение журнала также может предоставить вам более — и лучше структурированную — информацию о состоянии и работоспособности вашего приложения.

Обзор

Django использует и расширяет встроенный модуль Python logging для выполнения системного ведения журнала. Этот модуль подробно описан в документации Python; этот раздел предоставляет краткий обзор.

Состав участников

Конфигурация ведения журнала Python состоит из четырёх частей:

  • Журналисты
  • Обработчики
  • Фильтры
  • Форматировщики

Журналисты

Журналист — это точка входа в систему ведения журнала. Каждый журналист — это именованный контейнер, в который можно записывать сообщения для обработки.

Журналист настроен с уровнем журнала. Этот уровень журнала описывает степень важности сообщений, которые будет обрабатывать журналист. Python определяет следующие уровни журнала:

  • DEBUG: Информация низкого уровня о системе для отладки
  • INFO: Общая информация о системе
  • WARNING: Информация, описывающая незначительную проблему, которая произошла.
  • ERROR: Информация, описывающая серьёзную проблему, которая произошла.
  • CRITICAL: Информация, описывающая критическую проблему, которая произошла.

Каждое сообщение, которое записывается в журналист, — это Запись журнала. Каждая запись журнала также имеет уровень журнала, указывающий степень важности этого конкретного сообщения. Запись журнала также может содержать полезные метаданные, описывающие событие, которое регистрируется. Это может включать такие детали, как стек вызовов или код ошибки.

Когда сообщению предоставляется журналист, уровень важности сообщения сравнивается с уровнем важности журналиста. Если уровень важности сообщения соответствует или превышает уровень важности самого журналиста, сообщение будет подвергнуто дальнейшей обработке. В противном случае сообщение будет проигнорировано.

После того, как журналист определил, что сообщение необходимо обработать, оно передаётся Обработчику.

Обработчики

Обработчик — это механизм, который определяет, что происходит с каждым сообщением в журналисте. Он описывает определённое поведение ведения журнала, например, запись сообщения на экран, в файл или в сетевой сокет.

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

Журналист может иметь несколько обработчиков, и каждый обработчик может иметь разный уровень журнала. Таким образом, можно предоставить различные формы уведомлений в зависимости от важности сообщения. Например, можно установить один обработчик, который перенаправляет сообщения ERROR и CRITICAL в службу уведомлений, в то время как второй обработчик записывает все сообщения (включая сообщения ERROR и CRITICAL) в файл для последующего анализа.

Фильтры

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

По умолчанию любое сообщение журнала, соответствующее требованиям уровня важности, будет обработано. Однако при установке фильтра можно установить дополнительные критерии для процесса ведения журнала. Например, можно установить фильтр, который пропускает только сообщения ERROR из определённого источника.

Фильтры также могут использоваться для модификации записи журнала перед выводом. Например, можно написать фильтр, который понижает сообщения ERROR до уровня WARNING если выполнены определённые условия.

Фильтры могут быть установлены на журналистах или на обработчиках; несколько фильтров могут использоваться в цепочке для выполнения нескольких действий фильтрации.

Форматировщики

В конечном счёте, запись журнала должна быть представлена в виде текста. Форматировщики описывают точный формат этого текста. Форматировщик обычно состоит из строки форматирования Python, содержащей атрибуты LogRecord; однако вы также можете написать собственные форматировщики для реализации специфического поведения форматирования.

Безопасность

Система ведения журнала обрабатывает потенциально конфиденциальную информацию. Например, запись журнала может содержать информацию о веб-запросе или стеке вызовов, а также некоторые данные, которые вы собираете в собственных журналистах, также могут иметь последствия для безопасности. Вам нужно убедиться, что вы знаете:

  • какая информация собирается
  • где она будет храниться
  • как она будет передаваться
  • кто может к ней получить доступ.

Чтобы контролировать сбор конфиденциальной информации, вы можете явно указать определённую конфиденциальную информацию, которая будет исключена из отчётов об ошибках — прочтите больше о том, как фильтровать отчёты об ошибках.

AdminEmailHandler

Встроенный AdminEmailHandler заслуживает упоминания в контексте безопасности. Если включён его параметр include_html, отправляемое им электронное сообщение будет содержать полный стек вызовов с именами и значениями локальных переменных на каждом уровне стека, а также значениями настроек Django (иными словами, такой же уровень детализации, который показан на веб-странице, когда DEBUG имеет значение True).

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

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

Библиотека ведения журнала Python предоставляет несколько методов настройки ведения журнала, начиная от программного интерфейса и заканчивая конфигурационными файлами. По умолчанию Django использует формат dictConfig.

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

По умолчанию настройка LOGGING объединяется с стандартной конфигурацией ведения журнала Django с помощью следующего механизма.

Если ключ disable_existing_loggers в словаре LOGGING установлен в True (это значение dictConfig по умолчанию, если ключ отсутствует), то все журналисты из стандартной конфигурации будут отключены. Отключенные журналисты не являются удалёнными; журналист по-прежнему существует, но молча игнорирует всё, что записывается в него, не передавая даже записи родительскому журналисту. Поэтому следует очень осторожно использовать 'disable_existing_loggers': True; скорее всего, это не то, что вам нужно. Вместо этого вы можете установить disable_existing_loggers в False и переопределить некоторые или все стандартные журналисты; или вы можете установить LOGGING_CONFIG в None и сами обработать конфигурацию ведения журнала.

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

Примеры

Полная документация для dictConfig format — лучший источник информации о словарях конфигурации ведения журнала. Однако, чтобы вы имели представление о возможностях, вот несколько примеров.

Начнём с небольшой конфигурации, которая позволит выводить все сообщения журнала в консоль:

settings.py
import os

LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
        },
    },
    "root": {
        "handlers": ["console"],
        "level": "WARNING",
    },
}

Эта конфигурация настраивает родительский журналист root для отправки сообщений с уровнем важности WARNING и выше в обработчик консоли. Изменяя уровень на INFO или DEBUG, можно отображать больше сообщений. Это может быть полезно во время разработки.

Далее, мы можем добавить более детальное ведение журнала. Вот пример, как сделать систему ведения журнала, чтобы выводить больше сообщений только из журналиста с именем django:

settings.py
import os

LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
        },
    },
    "root": {
        "handlers": ["console"],
        "level": "WARNING",
    },
    "loggers": {
        "django": {
            "handlers": ["console"],
            "level": os.getenv("DJANGO_LOG_LEVEL", "INFO"),
            "propagate": False,
        },
    },
}

По умолчанию, эта конфигурация отправляет сообщения из логгера django уровня INFO или выше в консоль. Это тот же уровень, что и в стандартной конфигурации Django для ведения журналов, за исключением того, что стандартная конфигурация отображает записи журнала только когда DEBUG=True. Django не записывает многие сообщения уровня INFO. Однако с этой конфигурацией вы также можете установить переменную среды DJANGO_LOG_LEVEL=DEBUG, чтобы увидеть все подробные журналы отладки Django, которые очень подробны, поскольку включают все запросы к базе данных.

Вам не обязательно отправлять логи в консоль. Вот конфигурация, которая записывает все логи из логгера с именем django в локальный файл:

settings.py
LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "handlers": {
        "file": {
            "level": "DEBUG",
            "class": "logging.FileHandler",
            "filename": "/path/to/django/debug.log",
        },
    },
    "loggers": {
        "django": {
            "handlers": ["file"],
            "level": "DEBUG",
            "propagate": True,
        },
    },
}

Если вы используете этот пример, обязательно измените путь 'filename' на место, к которому имеет доступ для записи пользователь, запускающий приложение Django.

Наконец, вот пример довольно сложной конфигурации ведения журналов:

settings.py
LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "formatters": {
        "verbose": {
            "format": "{levelname} {asctime} {module} {process:d} {thread:d} {message}",
            "style": "{",
        },
        "simple": {
            "format": "{levelname} {message}",
            "style": "{",
        },
    },
    "filters": {
        "special": {
            "()": "project.logging.SpecialFilter",
            "foo": "bar",
        },
        "require_debug_true": {
            "()": "django.utils.log.RequireDebugTrue",
        },
    },
    "handlers": {
        "console": {
            "level": "INFO",
            "filters": ["require_debug_true"],
            "class": "logging.StreamHandler",
            "formatter": "simple",
        },
        "mail_admins": {
            "level": "ERROR",
            "class": "django.utils.log.AdminEmailHandler",
            "filters": ["special"],
        },
    },
    "loggers": {
        "django": {
            "handlers": ["console"],
            "propagate": True,
        },
        "django.request": {
            "handlers": ["mail_admins"],
            "level": "ERROR",
            "propagate": False,
        },
        "myproject.custom": {
            "handlers": ["console", "mail_admins"],
            "level": "INFO",
            "filters": ["special"],
        },
    },
}

Эта конфигурация ведения журналов выполняет следующие действия:

  • Указывает, что конфигурация находится в формате «dictConfig version 1». В настоящее время это единственная версия формата dictConfig.
  • Определяет два форматировщика:

    • simple, который выводит имя уровня журнала (например, DEBUG) и сообщение журнала.

      Строка format — это обычная строка форматирования Python, описывающая детали, которые должны быть выведены в каждой строке журнала. Полный список деталей, которые могут быть выведены, можно найти в Объекты форматировщика.

    • verbose, который выводит имя уровня журнала, сообщение журнала, а также время, процесс, поток и модуль, которые сгенерировали сообщение журнала.
  • Определяет два фильтра:

    • project.logging.SpecialFilter, использующий псевдоним special. Если этому фильтру нужны дополнительные аргументы, они могут быть предоставлены как дополнительные ключи в словаре конфигурации фильтра. В этом случае аргументу foo будет присвоено значение bar при создании экземпляра SpecialFilter.
    • django.utils.log.RequireDebugTrue, который пропускает записи, когда DEBUG имеет значение True.
  • Определяет два обработчика:

    • console, StreamHandler, который выводит любое сообщение INFO (или выше) в sys.stderr. Этот обработчик использует формат вывода simple.
    • mail_admins, AdminEmailHandler, который отправляет электронное письмо с любым сообщением ERROR (или выше) на адрес сайта ADMINS. Этот обработчик использует фильтр special.
  • Настраивает три логгера:

    • django, который передает все сообщения обработчику console.
    • django.request, который передает все сообщения ERROR обработчику mail_admins. Кроме того, этот логгер отмечен как не передающий сообщения. Это означает, что сообщения, записанные в django.request не будут обработаны логгером django.
    • myproject.custom, который передает все сообщения уровня INFO или выше, также прошедшие фильтр special, двум обработчикам — console, и mail_admins. Это означает, что все сообщения уровня INFO (или выше) будут выведены в консоль; сообщения уровня ERROR и CRITICAL также будут отправлены по электронной почте.

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

Если вы не хотите использовать формат dictConfig Python для настройки логгера, вы можете указать свой собственный метод настройки.

Настройка LOGGING_CONFIG определяет вызываемый объект, который будет использоваться для настройки логгеров Django. По умолчанию он указывает на функцию Python logging.config.dictConfig(). Однако, если вы хотите использовать другой процесс настройки, вы можете использовать любой другой вызываемый объект, который принимает один аргумент. Содержимое LOGGING будет предоставлено в качестве значения этого аргумента при настройке ведения журнала.

Отключение настройки ведения журнала

Если вы не хотите настраивать ведение журнала (или хотите настроить его вручную), вы можете установить LOGGING_CONFIG на None. Это отключит процесс настройки для стандартной конфигурации ведения журнала Django.

Установка LOGGING_CONFIG на None означает только отключение автоматического процесса настройки, а не самого ведения журнала. Если вы отключите процесс настройки, Django все равно будет вызывать функции ведения журнала, используя по умолчанию определенное поведение ведения журнала.

Вот пример, который отключает настройку ведения журнала Django и затем настраивает ведение журнала вручную:

settings.py
LOGGING_CONFIG = None

import logging.config

logging.config.dictConfig(...)

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

© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/5.1/topics/logging/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API