Spec-Zone.ru › Django 1.9

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

При работе с общедоступным сайтом всегда следует выключать настройку 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_CLASSES включает django.middleware.common.BrokenLinkEmailsMiddleware.

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

В более старых версиях ошибки 404 не игнорировались, когда referer был равен запрошенному URL.

Примечание

BrokenLinkEmailsMiddleware должна располагаться перед другими сред, перехватывающими ошибки 404, такими как LocaleMiddleware или FlatpageFallbackMiddleware. Разместите её в верхней части настройки MIDDLEWARE_CLASSES.

Вы можете указать 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]
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.9/howto/error-reporting/

Spec-Zone.ru

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