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

Когда ваш сайт работает публично вы всегда должны отключать опцию отладки DEBUG. Это сделает запуск вашего сервера намного быстрее и избавит посетителей от созерцания детальной информации, отображаемой на странице в случае ошибок.

Однако, отключив вывод отладочной информации, вы рискуете никогда не узнать об имеющихся на сайте ошибках при обращении к публичным страницам. Но вам нужно отслеживать появление ошибок на уже развёрнутых сайтах, и Django может быть сконфигурирован таким образом, чтобы всегда предоставлять вам необходимые отчёты.

Уведомления на email

Ошибки сервера

Когда опция DEBUG установлена в False, Django высылает отчёт пользователям, указанным в секции ADMINS, в случае, если ваш код вызывает исключения, которые не могут быть обработаны и приводят к внутренней ошибке сервера (HTTP status code 500). Администраторам немедленно поступит соответствующее уведомление. Администраторам (ADMINS) будет доступно писание ошибки, вывод трассировочной информации и указание на HTTP запрос, который вызвал ошибку.

Примечание

Для отправки электронного уведомления Django потребуется указать несколько параметров для успешного подключения к почтовому серверу. По крайней мере, нужно указать имя хоста (EMAIL_HOST) и, возмжно, имя пользователя (EMAIL_HOST_USER) и его пароль (EMAIL_HOST_PASSWORD), хотя могут потребоваться и другие настройки , это зависит от конфигурации почтового сервера. См. документацию по настройке проекта, где приведён полный список возможных опций.

По-умолчанию Django отправит отчёт на адрес root@localhost. Однако некоторые провайдеры отбрасывают любые запросы на этот адрес. Для указания другого адреса исправьте настройки параметра SERVER_EMAIL.

Чтобы включить такое поведение укажите почтовые адреса в секции ADMINS.

См.также

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

404 ошибка

Django может уведомлять вас о неработающих ссылках (ошибка 404 “страница не найдена”). Сообщения о 404 ошибках отправляются при условии, что:

Если оба условия выполнены, Django вышлет отчёт пользователям, указанным в секции MANAGERS, когда при запросе к странице возникает ошибка 404 (Это не относится к ошибке 404, не имеющей ссылки на страницу – как правило, в этом случае ошибка связана с тем, что пользователь вводит неверный адрес).

Примечание

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

Вы можете отключить отчёты о 404 ошибке, настроив IGNORABLE_404_URLS. Это должен быть кортеж со скомпилированными объектами регулярынх выражений. Например:

import re
IGNORABLE_404_URLS = (
    re.compile(r'\.(php|cgi)$'),
    re.compile(r'^/phpmyadmin/'),
)

В этом примере уведомление об ошибке 404 не будет присылаться, если URL страницы заканчивается на .php или .cgi. Также в исключения добавлена директория /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.

Однако, некоторая информация может быть конфиденциальной и совершенно не подходит для отслеживания, к таким моментам можно отнести пароль пользователя или номер кредитной карты. Django предлагает несколько декораторов для контроля информации, которая должна быть отфильтрована при отправке отчётов на боевом сервере (то есть там, где DEBUG установлен в False): sensitive_variables() и sensitive_post_parameters().

sensitive_variables(*variables)

Если функция (или представление регулярного выражения) в вашем коде использует локальные переменные, содержащие конфиденциальную информацию, вы можете предотвратить появление этих переменных при отправке отчётов при помощи декоратора 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 будет открытым.

Систематическое скрытие всех локальных переменных функции из журнала ошибок (error logs) не требует никаких аргументов декоратора sensitive_variables:

@sensitive_variables()
def my_function():
    ...

When using mutiple decorators

Если переменная, значение которой вы хотите скрыть, также является аргументом функции (как ‘user‘ в приведённом примере), и декорируемая функция имеет множество декораторов, убедитесь, что @sensitive_variables находится на самом верху цепочки. Это позволит также скрыть аргументы функции, взаимодействующие с другими декораторами:

@sensitive_variables('user', 'pw', 'cc')
@some_decorator
@another_decorator
def process_info(user):
    ...
sensitive_post_parameters(*parameters)

Если одно из представлений объекта 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 параметров из журнала ошибок (error logs) не требует никаких аргументов декоратора 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 в системе аутентификации) для предотвращения утечки конфиденциальной информации, такой как пароли пользователей.

Настройка отчета об ошибке

Декораторы sensitive_variables() и sensitive_post_parameters() отмечают небезопасные аргументы и POST аргументы объекта HttpRequest, которые передаются в функцию. При формировании отчета об ошибке эти данные фильтруются. Фильтрация выполняется классом django.views.debug.SafeExceptionReporterFilter. Этот класс заменит отмеченные декоратором данные “звездочками” (**********) при формировании отчета. Вы можете создать собственный класс фильтрации и указать его в настройке 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
SafeExceptionReporterFilter.is_active(self, request)

Возвращает True, указывая фильтровать данные или нет. По умолчанию фильтрация выполняется при DEBUG равном False.

SafeExceptionReporterFilter.get_request_repr(self, request)

Возвращает строковое представление объекта запроса, то есть результат repr(request), но использует отфильтрованные POST параметры из метода SafeExceptionReporterFilter.get_post_parameters().

SafeExceptionReporterFilter.get_post_parameters(self, request)

Возвращает отфильтрованный словарь POST параметров. По умолчанию заменяет небезопасные данные “звездочками” (**********).

SafeExceptionReporterFilter.get_traceback_frame_variables(self, request, tb_frame)

Возвращает отфильтрованный словарь локальных переменных. По умолчанию заменяет небезопасные данные “звездочками” (**********).

См.также

Вы также можете изменить формирование для отчета создав собственный мидлвар обработки ошибок. Советуем сохранить поведение Django и возвращать отчет об ошибке только при DEBUG равном False.