Записывайте все ошибки в консоль или файл на сайте Django - PullRequest
14 голосов
/ 27 марта 2009

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

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

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

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

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

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

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

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

Ответы [ 5 ]

13 голосов
/ 27 марта 2009

Это немного экстремально, но для целей отладки вы можете включить настройку 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 (например: импорт thisclassdoesnotexist в urs. ру). Я новичок в Django / Python. Это из-за некоторого различия между ошибками во время выполнения и во время компиляции?

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

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

6 голосов
/ 30 марта 2009

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

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

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

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

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

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

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

2 голосов
/ 27 марта 2009

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

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

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

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

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

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

1 голос
/ 13 ноября 2009
0 голосов
/ 29 марта 2009

Если вы используете систему * nix, вы можете

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...