Отчёт об ошибках
При работе с публичным сайтом всегда следует отключать настройку 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, а в запросе есть поле «referrer». Он не отправляет электронные письма для ошибок 404, в которых нет поля «referrer» – это обычно просто люди, которые вводят неправильные URL или поломанные веб-боты. Он также игнорирует ошибки 404, когда значение «referrer» равно запрошенному 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, начинающиеся с /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)[source] -
Если функция (как представление, так и любой обычный обратный вызов) в вашем коде использует локальные переменные, которые могут содержать конфиденциальную информацию, вы можете предотвратить включение значений этих переменных в отчёты об ошибках с помощью декоратора
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)[source] -
Если один из ваших представлений получает объект
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_numberPOST будут скрыты и заменены звёздочками (**********) в представлении запроса внутри сообщений об ошибках, в то время как значение параметра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[source]
-
SafeExceptionReporterFilter.is_active(request)[source] -
Возвращает
Trueдля активации фильтрации, выполняемой другими методами. По умолчанию фильтр активен, еслиDEBUGимеет значениеFalse.
-
SafeExceptionReporterFilter.get_post_parameters(request)[source] -
Возвращает отфильтрованный словарь параметров POST. По умолчанию он заменяет значения чувствительных параметров звёздочками (
**********).
-
SafeExceptionReporterFilter.get_traceback_frame_variables(request, tb_frame)[source] -
Возвращает отфильтрованный словарь локальных переменных для данного кадра трассировки. По умолчанию он заменяет значения чувствительных переменных звёздочками (
**********).
См. также
Вы также можете настроить пользовательский отчет об ошибках, написав собственный фрагмент обработчика исключений. Если вы пишете пользовательскую обработку ошибок, рекомендуется имитировать встроенную обработку ошибок Django и сообщать/логировать ошибки только если DEBUG имеет значение False.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/2.0/howto/error-reporting/