Spec-Zone.ru › Django 5.0

Как управлять отчетами об ошибках

При работе с публичным сайтом вы всегда должны отключить настройку DEBUG. Это значительно ускорит работу вашего сервера и предотвратит показ злоумышленникам деталей вашего приложения, которые могут быть раскрыты страницами ошибок.

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

Отчеты по электронной почте

Ошибки сервера

Когда DEBUG установлено в False, Django будет отправлять электронные письма пользователям, указанным в настройке ADMINS, всякий раз, когда ваш код вызывает необработанное исключение и приводит к внутренней ошибке сервера (строго говоря, для любого ответа с кодом HTTP статуса 500 или выше). Это обеспечивает администраторам мгновенное уведомление об ошибках. В письме к ADMINS будет описание ошибки, полный трассировочный вывод Python, а также информация об HTTP-запросе, который вызвал ошибку.

Примечание

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

По умолчанию Django будет отправлять письма от root@localhost. Однако некоторые поставщики почтовых услуг отклоняют все письма с этого адреса. Чтобы использовать другой адрес отправителя, измените настройку SERVER_EMAIL.

Чтобы активировать это поведение, поместите адреса получателей в настройку ADMINS.

См. также

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

Ошибки 404

Django также можно настроить на отправку писем об ошибочных ссылках (ошибки 404 «страница не найдена»). Django отправляет письма об ошибках 404, когда:

  • DEBUG установлено в False;
  • Настройка MIDDLEWARE включает django.middleware.common.BrokenLinkEmailsMiddleware.

Если эти условия выполнены, Django отправит письма пользователям, указанным в настройке MANAGERS, всякий раз, когда ваш код вызывает ошибку 404, и запрос содержит referer. Он не будет беспокоиться об отправке писем для 404 без referer — это обычно люди, вводящие неверные URL-адреса или неисправные веб-боты. Также игнорируются ошибки 404, когда referer равен запрошенному URL, так как это также поведение неисправных веб-ботов.

Примечание

BrokenLinkEmailsMiddleware должен предшествовать другому middleware, который перехватывает ошибки 404, такому как LocaleMiddleware или FlatpageFallbackMiddleware. Поместите его в начало вашей настройки MIDDLEWARE.

Вы можете сказать Django, чтобы он прекратил отсылать конкретные ошибки 404, скорректировав настройку IGNORABLE_404_URLS. Она должна быть списком скомпилированных объектов регулярных выражений. Например:

import re

IGNORABLE_404_URLS = [
    re.compile(r"\.(php|cgi)$"),
    re.compile(r"^/phpmyadmin/"),
]

В этом примере ошибка 404 для любого URL, заканчивающегося на .php или .cgi, не будет сообщаться. То же самое относится к любому URL, начинающемуся с /phpmyadmin/.

Следующий пример показывает, как исключить некоторые распространенные URL-адреса, которые часто запрашивают браузеры и веб-боты:

import re

IGNORABLE_404_URLS = [
    re.compile(r"^/apple-touch-icon.*\.png$"),
    re.compile(r"^/favicon\.ico$"),
    re.compile(r"^/robots\.txt$"),
]

(Обратите внимание, что это регулярные выражения, поэтому мы ставим обратную косую черту перед точками, чтобы избежать их интерпретации как метасимволов.)

Если вы хотите дополнительно настроить поведение django.middleware.common.BrokenLinkEmailsMiddleware (например, чтобы игнорировать запросы от веб-ботов), вы должны создать его подкласс и переопределить его методы.

См. также

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

Фильтрация отчетов об ошибках

Предупреждение

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

Фильтрация конфиденциальной информации

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

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

sensitive_variables(*variables)

Если функция (как представление, так и любой обычный вызов обратного вызова) в вашем коде использует локальные переменные, которые могут содержать конфиденциальную информацию, вы можете предотвратить включение значений этих переменных в отчеты об ошибках, используя декоратор sensitive_variables:

from django.views.decorators.debug import sensitive_variables


@sensitive_variables("user", "pw", "cc")
def process_info(user):
    pw = user.pass_word
    cc = user.credit_card_number
    name = user.name
    ...

В приведенном выше примере значения переменных user, pw и cc будут скрыты и заменены звездочками (**********) в отчетах об ошибках, а значение переменной name будет раскрыто.

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

@sensitive_variables()
def my_function(): ...

Использование нескольких декораторов

Если переменная, которую вы хотите скрыть, также является аргументом функции (например, ‘user’ в следующем примере), и если у декорируемой функции есть несколько декораторов, убедитесь, что вы поместили @sensitive_variables в начало цепочки декораторов. Таким образом, она также скроет аргумент функции, поскольку он передается через другие декораторы:

@sensitive_variables("user", "pw", "cc")
@some_decorator
@another_decorator
def process_info(user): ...
Изменено в Django 5.0:

Добавлена поддержка обёртки async функций.

sensitive_post_parameters(*parameters)

Если один из ваших представлений получает объект HttpRequest с POST parameters, потенциально содержащий конфиденциальную информацию, вы можете предотвратить включение значений этих параметров в сообщения об ошибках, используя декоратор sensitive_post_parameters:

from django.views.decorators.debug import sensitive_post_parameters


@sensitive_post_parameters("pass_word", "credit_card_number")
def record_user_profile(request):
    UserProfile.create(
        user=request.user,
        password=request.POST["pass_word"],
        credit_card=request.POST["credit_card_number"],
        name=request.POST["name"],
    )
    ...

В приведённом примере значения для параметров pass_word и credit_card_number POST будут скрыты и заменены звёздочками (**********) в представлении запроса внутри сообщений об ошибках, в то время как значение параметра name будет раскрыто.

Чтобы систематически скрывать все параметры POST запроса в сообщениях об ошибках, не передавайте ни одного аргумента декоратору sensitive_post_parameters:

@sensitive_post_parameters()
def my_view(request): ...

Все параметры POST систематически отфильтровываются из сообщений об ошибках для определённых представлений django.contrib.auth.views (login, password_reset_confirm, password_change, и add_view и user_change_password в админ-панели auth), чтобы предотвратить утечку конфиденциальной информации, такой как пароли пользователей.

Изменено в Django 5.0:

Добавлена поддержка обертывания функций async.

Настраиваемые сообщения об ошибках

Все sensitive_variables() и sensitive_post_parameters() делают следующее: соответственно, добавляют к декорируемой функции имена конфиденциальных переменных и добавляют к объекту HttpRequest имена конфиденциальных параметров POST, чтобы эта конфиденциальная информация могла быть отфильтрована из отчётов при возникновении ошибки. Фактический отбор выполняется фильтром отчётов об ошибках по умолчанию Django: django.views.debug.SafeExceptionReporterFilter. Этот фильтр использует аннотации декораторов для замены соответствующих значений звёздочками (**********) при создании отчётов об ошибках. Если вы хотите переопределить или настроить это поведение по умолчанию для всего сайта, вам необходимо определить собственный класс фильтра и указать Django использовать его через настройку DEFAULT_EXCEPTION_REPORTER_FILTER:

DEFAULT_EXCEPTION_REPORTER_FILTER = "path.to.your.CustomExceptionReporterFilter"

Вы также можете более точно управлять фильтром, который используется в конкретном представлении, установив атрибут HttpRequest’s exception_reporter_filter:

def my_view(request):
    if request.user.is_authenticated:
        request.exception_reporter_filter = CustomExceptionReporterFilter()
    ...

Ваш пользовательский класс фильтра должен наследоваться от django.views.debug.SafeExceptionReporterFilter и может переопределить следующие атрибуты и методы:

class SafeExceptionReporterFilter
cleansed_substitute

Строковое значение для замены конфиденциальных значений. По умолчанию значения конфиденциальных переменных заменяются звёздочками (**********).

hidden_settings

Компилированный объект регулярного выражения, используемый для сопоставления настроек и значений request.META, рассматриваемых как конфиденциальные. По умолчанию эквивалентно:

import re

re.compile(r"API|TOKEN|KEY|SECRET|PASS|SIGNATURE|HTTP_COOKIE", flags=re.IGNORECASE)
Изменено в Django 4.2:

HTTP_COOKIE был добавлен.

is_active(request)

Возвращает True для активации фильтрации в get_post_parameters() и get_traceback_frame_variables(). По умолчанию фильтр активен, если DEBUG равно False. Обратите внимание, что конфиденциальные значения request.META всегда отфильтровываются вместе с конфиденциальными значениями настроек, как описано в документации DEBUG.

get_post_parameters(request)

Возвращает отфильтрованный словарь параметров POST. Конфиденциальные значения заменяются на cleansed_substitute.

get_traceback_frame_variables(request, tb_frame)

Возвращает отфильтрованный словарь локальных переменных для заданного кадра стека отладки. Конфиденциальные значения заменяются на cleansed_substitute.

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

DEFAULT_EXCEPTION_REPORTER = "path.to.your.CustomExceptionReporter"

Отчётчик об ошибках отвечает за компиляцию данных отчёта об ошибках и их форматирование как текста или HTML. (Отчётчик об ошибках использует DEFAULT_EXCEPTION_REPORTER_FILTER при подготовке данных отчёта об ошибках.)

Ваш пользовательский класс отчётчика должен наследоваться от django.views.debug.ExceptionReporter.

class ExceptionReporter
html_template_path

Свойство, которое возвращает pathlib.Path, представляющий абсолютный путь к файловой системе к шаблону для рендеринга HTML-представления исключения. По умолчанию использует шаблон Django.

text_template_path

Свойство, которое возвращает pathlib.Path, представляющий абсолютный путь к файловой системе к шаблону для рендеринга текстового представления исключения. По умолчанию использует шаблон Django.

get_traceback_data()

Возвращает словарь, содержащий информацию о стеке отладки.

Это основной пункт расширения для настройки отчётов об ошибках, например:

from django.views.debug import ExceptionReporter


class CustomExceptionReporter(ExceptionReporter):
    def get_traceback_data(self):
        data = super().get_traceback_data()
        # ... remove/add something here ...
        return data
get_traceback_html()

Возвращает HTML-версию отчёта об ошибке.

Используется для HTML-версии страницы ошибки HTTP 500.

get_traceback_text()

Возвращает текстовую версию отчёта об ошибке.

Используется для текстовой версии страницы ошибки HTTP 500 и отчётов по электронной почте.

Как и с классом фильтра, вы можете управлять тем, какой класс отчётчика об ошибках использовать в данном представлении, установив атрибут HttpRequest’s exception_reporter_class:

def my_view(request):
    if request.user.is_authenticated:
        request.exception_reporter_class = CustomExceptionReporter()
    ...

См. также

Вы также можете настроить отчёт об ошибке, написав пользовательский фрагмент обработчика исключений. Если вы пишете пользовательскую обработку ошибок, рекомендуется имитировать встроенную обработку ошибок Django и сообщать/логировать ошибки только если DEBUG равно False.

© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/5.0/howto/error-reporting/

Spec-Zone.ru

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