Как управлять отчетами об ошибках
При работе с публичным сайтом всегда следует выключать настройку 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)[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"], ) ...В приведенном выше примере значения параметров 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"
Вы также можете более точно управлять тем, какой фильтр использовать в конкретном представлении, установив атрибут 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] -
-
cleansed_substitute -
Строковое значение, которое будет использоваться для замены чувствительного значения. По умолчанию значения чувствительных переменных заменяются звёздочками (
**********).
-
Компилированный объект регулярного выражения, используемый для сопоставления настроек и
request.METAзначений, считающихся чувствительными. По умолчанию эквивалентен:import re re.compile(r"API|AUTH|TOKEN|KEY|SECRET|PASS|SIGNATURE|HTTP_COOKIE", flags=re.IGNORECASE)
Изменено в Django 5.2:Было добавлено понятие
AUTH.
-
is_active(request)[source] -
Возвращает
True, чтобы активировать фильтрацию вget_post_parameters()иget_traceback_frame_variables(). По умолчанию фильтр активен, еслиDEBUGимеет значениеFalse. Обратите внимание, что чувствительныеrequest.METAзначения всегда фильтруются вместе с чувствительными значениями настроек, как описано в документации кDEBUG.
-
get_post_parameters(request)[source] -
Возвращает отфильтрованный словарь параметров POST. Чувствительные значения заменяются на
cleansed_substitute.
-
get_traceback_frame_variables(request, tb_frame)[source] -
Возвращает отфильтрованный словарь локальных переменных для заданного кадра трассировки. Чувствительные значения заменяются на
cleansed_substitute.
-
Если вам нужно настроить сообщения об ошибках, выходящие за рамки фильтрации, вы можете указать пользовательский класс отчётчика об ошибках, определив настройку DEFAULT_EXCEPTION_REPORTER:
DEFAULT_EXCEPTION_REPORTER = "path.to.your.CustomExceptionReporter"
Отчётчик об ошибках отвечает за компиляцию данных отчёта об ошибках и форматирование их в текст или HTML в соответствии с этим. (Отчётчик об ошибках использует DEFAULT_EXCEPTION_REPORTER_FILTER при подготовке данных отчёта об ошибках.)
Ваш пользовательский класс отчётчика должен наследоваться от django.views.debug.ExceptionReporter.
-
class ExceptionReporter[source] -
-
html_template_path[source] -
Свойство, которое возвращает
pathlib.Path, представляющий абсолютный путь к файловой системе к шаблону для рендеринга HTML представления исключения. По умолчанию используется шаблон Django.
-
text_template_path[source] -
Свойство, которое возвращает
pathlib.Path, представляющий абсолютный путь к файловой системе к шаблону для рендеринга простого текстового представления исключения. По умолчанию используется шаблон Django.
-
get_traceback_data()[source] -
Возвращает словарь, содержащий информацию о трассировке.
Это основная точка расширения для настройки сообщений об ошибках, например:
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()[source] -
Возвращает HTML-версию отчёта об ошибке.
Используется для HTML-версии страницы ошибки HTTP 500.
-
get_traceback_text()[source] -
Возвращает текстовую версию отчёта об ошибке.
Используется для текстовой версии страницы ошибки 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/5.2/howto/error-reporting/