Spec-Zone.ru › Django 1.10

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

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

Изменено в Django 1.9:

В более ранних версиях ошибки 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'],
    )
    ...

В приведённом примере значения для параметров 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\'s 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/1.10/howto/error-reporting/

Spec-Zone.ru

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