Отчёт об ошибках
При работе с публичным сайтом всегда следует отключать параметр 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, и запрос содержит ссылку на предыдущую страницу. Django не беспокоится об отправке писем для ошибок 404, у которых нет ссылки на предыдущую страницу – это обычно люди, вводящие неверные URL-адреса, или некорректные веб-боты. Также игнорируются ошибки 404, когда ссылка на предыдущую страницу совпадает с запрошенным 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.1/howto/error-reporting/