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

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

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

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

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

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

Примечание

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

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

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

См.также

Письма об ошибках сервера отправляются с помощью фреймворка протоколирования, поэтому вы можете настроить это поведение с помощью customizing your logging configuration.

404 ошибки

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

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

Примечание

BrokenLinkEmailsMiddleware должен появляться перед другими промежуточными программами, перехватывающими 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, начинающемся с .cgi.

В следующем примере показано, как исключить некоторые обычные 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 записываются в журнал с помощью фреймворка протоколирования. По умолчанию эти записи журнала игнорируются, но вы можете использовать их для сообщения об ошибках, написав обработчик и configuring logging соответствующим образом.

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

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

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

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

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

Однако иногда некоторые типы информации могут быть слишком чувствительными и, следовательно, не могут быть уместны для отслеживания, например, пароль пользователя или номер кредитной карты. Поэтому в дополнение к фильтрации параметров, которые кажутся чувствительными, как описано в документации 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'],
    )
    ...

В приведенном выше примере значения POST-параметров pass_word и credit_card_number будут скрыты и заменены звездочками (**********) в представлении запроса внутри отчетов об ошибках, тогда как значение параметра 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'

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

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

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

class SafeExceptionReporterFilter[исходный код]
SafeExceptionReporterFilter.is_active(request)[исходный код]

Возвращает True для активации фильтрации, осуществляемой в других методах. По умолчанию фильтр активен, если DEBUG равен False.

SafeExceptionReporterFilter.get_post_parameters(request)[исходный код]

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

SafeExceptionReporterFilter.get_traceback_frame_variables(request, tb_frame)[исходный код]

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

См.также

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

Вернуться на верх