Записывать все ошибки в консоль или файл на сайте Django

Как я могу заставить Django 1.0 писать ошибки all на консоль или файл журнала при запуске runerver в режиме отладки?

Я пробовал использовать класс промежуточного программного обеспечения с функцией process_exception, как описано в принятом ответе на этот вопрос:

Как регистрировать ошибки сервера на сайтах django

Функция process_exception вызывается для некоторых исключений (например: assert (False) в views.py), но process_exception не вызывается для других ошибок, таких как ImportErrors (например: import thisclassdoesnotexist в urs.py). Я новичок в Django/Python. Это из-за какого-то различия между ошибками времени выполнения и времени компиляции? Но тогда я ожидал бы, что runerver будет жаловаться, если это была ошибка времени компиляции, и это не так.

Я наблюдал фантастическую презентацию Саймона Уиллисона о отладке Django (http://simonwillison.net/2008/May/22/debugging/), но я не видел вариант, который будет работать хорошо для меня.

В случае, если это уместно, я пишу приложение Facebook, а Facebook маскирует ошибки HTTP 500 с их собственным сообщением, а не демонстрирует удивительно информативную 500-страничную Django. Поэтому мне нужен способ для всех типов ошибок, которые должны быть записаны в консоль или файл.

Изменить: Я предполагаю, что мое ожидание заключается в том, что если Django может вернуть страницу с ошибкой 500 с большим количеством деталей, когда у меня плохой импорт (ImportError) в urls.py, он должен иметь возможность писать те же детали к консоли или файлу без необходимости добавлять дополнительную обработку исключений в код. Я никогда не видел обработку исключений вокруг операторов импорта.

Спасибо, Джефф

Ответы

Ответ 1

Это немного экстремально, но для целей отладки вы можете включить параметр DEBUG_PROPAGATE_EXCEPTIONS. Это позволит вам настроить собственную обработку ошибок. Самый простой способ настроить эту обработку ошибок - переопределить sys.excepthook. Это прекратит ваше приложение, но оно будет работать. Могут быть вещи, которые вы можете сделать, чтобы это не убило ваше приложение, но это будет зависеть от того, на какой платформе вы его развертываете. Во всяком случае, никогда не используйте это в производстве!

Для производства вам в значительной степени придется иметь обширную обработку ошибок. Один из методов, который я использовал, выглядит примерно так:

>>> def log_error(func):
...     def _call_func(*args, **argd):
...         try:
...             func(*args, **argd)
...         except:
...             print "error" #substitute your own error handling
...     return _call_func
...
>>> @log_error
... def foo(a):
...     raise AttributeError
...
>>> foo(1)
error

Если вы используете log_error в качестве декоратора на вашем представлении, он автоматически обрабатывает все ошибки, произошедшие внутри него.

Функция исключения _ вызывается для некоторых исключений (например: assert (False) в views.py), но процесс _ исключение не вызвано для других ошибок, таких как ImportErrors (например: import thisclassdoesnotexist в urs. ру). Я новичок в Django/Python. Это из-за какого-то различия между ошибками времени выполнения и времени компиляции?

В Python все ошибки являются ошибками во время выполнения. Причина, по которой это вызывает проблемы, состоит в том, что эти ошибки возникают сразу же после импорта модуля до того, как ваш вызов когда-либо будет вызван. Первый метод, который я опубликовал, будет ловить ошибки, подобные этим для отладки. Возможно, вы сможете что-то понять для производства, но я бы сказал, что у вас есть проблемы, если вы получаете ImportErrors в производственном приложении (и вы не выполняете динамического импорта).

Инструмент, подобный pylint, может помочь вам устранить эти проблемы.

Ответ 2

Функция process_exception - это для некоторых исключений (например: assert (False) в views.py), но process_exception не получает вызвал другие ошибки, такие как ImportErrors (например: импорт thisclassdoesnotexist в urs.py). я новый для Django/Python. Это потому, что какого-то различия между временем выполнения и ошибки времени компиляции?

Нет, это просто потому, что промежуточное программное обеспечение process_exception вызывается только в том случае, если в представлении отображается исключение.

Я думаю, что DEBUG_PROPAGATE_EXCEPTIONS (как упоминалось ранее Джейсоном Бейкером) - вот что вам нужно здесь, но я не думаю, что вы не необходимо сделать что-нибудь дополнительное (например, sys.excepthook и т.д.), если вы просто хотите, чтобы трассировка была сбрасываема на консоль.

Если вы хотите сделать что-нибудь более сложное с ошибкой (т.е. сбросить его в файл или DB), самым простым подходом будет get_request_exception signal, который Django отправляет для любого исключения, связанного с запросом, независимо от того, было ли оно поднято в представлении или нет.

get_response и handle_uncaught_exception методы django.core.handlers.BaseHandler - поучительное (и краткое) чтение в этой области.

не добавляя дополнительных обработка исключений для кода. Я никогда не видел обработку исключений импорт.

Посмотрите еще немного, вы увидите это (часто в тех случаях, когда вы хотите обработать отсутствие зависимости каким-то определенным образом). Тем не менее, это было бы, конечно, довольно уродливо, если бы вам пришлось посыпать дополнительные блоки исключений, кроме всего кода, чтобы сделать глобальное изменение того, как обрабатываются исключения!

Ответ 3

Во-первых, очень мало ошибок времени компиляции, которые вы увидите в журнале исключений. Если ваш код Python не имеет действительного синтаксиса, он умирает задолго до того, как журналы будут открыты для записи.

В режиме Django runerver запись "print" записывается в stdout, что вы можете видеть. Однако это не очень хорошее долгосрочное решение, поэтому не рассчитывайте на это.

Если Django работает под Apache, это зависит от того, какой подключаемый модуль вы используете. mod_python нелегко справиться. mod_wsgi можно принуждать к отправке stdout и stderr в файл журнала.

Лучше всего использовать logging. Поместите инициализацию в верхний уровень urls.py, чтобы настроить ведение журнала. (Или, возможно, ваш settings.py)

Убедитесь, что каждый модуль имеет регистратор, доступный для записи сообщений журнала.

Убедитесь, что каждый вызов веб-сервисов, который вы создаете, имеет вокруг него блок try/except, и вы записываете исключения из своего журнала.

Ответ 5

Если вы находитесь в системе * nix, вы можете

записать в журнал (например, mylog.txt) в python затем запустите "tail -f mylog.txt" в консоли

это удобный способ просмотра любого вида журнала в режиме реального времени