Spec-Zone.ru › Django 3.2

Отчеты об ошибках

При работе с общедоступным сайтом всегда следует выключать параметр 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):
    ...
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), чтобы предотвратить утечку конфиденциальной информации, такой как пароли пользователей.

Кастомные отчёты об ошибках

Все 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 в 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
Новое в Django 3.1.

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

hidden_settings
Новое в Django 3.1.

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

import re

re.compile(r'API|TOKEN|KEY|SECRET|PASS|SIGNATURE', flags=re.IGNORECASE)
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.

Новое в Django 3.1.

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

DEFAULT_EXCEPTION_REPORTER = 'path.to.your.CustomExceptionReporter'

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

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

class ExceptionReporter
html_template_path
Новое в Django 3.2.

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

text_template_path
Новое в Django 3.2.

Свойство, возвращающее 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 в 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/3.2/howto/error-reporting/

Spec-Zone.ru

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