Как вы регистрируете ошибки сервера на сайтах Django?

175

Так, играя с развитием я могу просто установить settings.DEBUGв Trueи если встречается , сообщение об ошибке , я могу видеть , что это красиво отформатирована, с трассировкой хороший стек и запрашивают информацию.

Но на производственном сайте я бы предпочел использовать DEBUG=Falseи показывать посетителям некоторую стандартную страницу ошибки 500 с информацией, над которой я сейчас работаю над исправлением этой ошибки;)
В то же время я хотел бы иметь какой-либо способ регистрации всех эта информация (трассировка стека и информация запроса) в файл на моем сервере - так что я могу просто вывести ее на консоль и наблюдать за ошибками, прокручивать журнал каждый час или что-то в этом роде.

Какие решения для ведения журнала вы бы порекомендовали для django-сайта, который бы соответствовал этим простым требованиям? У меня есть приложение, работающее как fcgiсервер, и я использую веб-сервер apache в качестве внешнего интерфейса (хотя собираюсь перейти на lighttpd).

кендер
источник
кое-что из поля
Cherian
2
Часовой для просмотра журналов: readthedocs.org/docs/sentry/en/latest/index.html
Cherian
Ссылка, которой поделилась Чериан, теперь мертва. Если вы попытаетесь найти Sentry, вы, скорее всего, найдете материал для их платного официального экземпляра, но вот ссылка для настройки автономного экземпляра: docs.sentry.io/server Кроме того, вот текущее поддерживаемое хранилище: github .com / getsentry / sentry
lehiester

Ответы:

103

Что ж, когда DEBUG = FalseDjango автоматически отправит полный отчет об обнаружении любой ошибки каждому человеку, указанному в ADMINSнастройке, который получит вам уведомления практически бесплатно. Если вам нужен более детальный контроль, вы можете написать и добавить в свои настройки класс промежуточного программного обеспечения, который определяет метод с именем process_exception(), который будет иметь доступ к возникшему исключению:

http://docs.djangoproject.com/en/dev/topics/http/middleware/#process-exception

process_exception()Затем ваш метод может выполнять запись любого типа: запись в консоль, запись в файл и т. Д. И т. Д.

Редактировать: хотя это немного менее полезно, вы также можете прослушивать got_request_exceptionсигнал, который будет отправляться всякий раз, когда возникает исключение во время обработки запроса:

http://docs.djangoproject.com/en/dev/ref/signals/#got-request-exception

Однако это не дает вам доступа к объекту исключения, поэтому с методом промежуточного программного обеспечения работать намного проще.

Джеймс Беннетт
источник
7
Обратите внимание, что использование logging.exception('Some message')со стандартным модулем журналирования в Python прекрасно работает в обработчике sginal got_request_exception, если все, что вам нужно, это выйти из трассировки стека. Другими словами, трассировка по-прежнему доступна в got_request_exception.
ТМ.
исключение, переданное в process_exception, похоже, не имеет трассировки стека, есть ли способ получить это?
Ник Б.Л.
79

Как уже упоминалось, Django Sentry - это хороший способ, но для его правильной настройки требуется немало усилий (в качестве отдельного веб-сайта). Если вы просто хотите записать все в простой текстовый файл, вот конфигурация регистрации, чтобы поместить вsettings.py

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        # Include the default Django email handler for errors
        # This is what you'd get without configuring logging at all.
        'mail_admins': {
            'class': 'django.utils.log.AdminEmailHandler',
            'level': 'ERROR',
             # But the emails are plain text by default - HTML is nicer
            'include_html': True,
        },
        # Log to a text file that can be rotated by logrotate
        'logfile': {
            'class': 'logging.handlers.WatchedFileHandler',
            'filename': '/var/log/django/myapp.log'
        },
    },
    'loggers': {
        # Again, default Django configuration to email unhandled exceptions
        'django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
        },
        # Might as well log any errors anywhere else in Django
        'django': {
            'handlers': ['logfile'],
            'level': 'ERROR',
            'propagate': False,
        },
        # Your own app - this assumes all your logger names start with "myapp."
        'myapp': {
            'handlers': ['logfile'],
            'level': 'WARNING', # Or maybe INFO or DEBUG
            'propagate': False
        },
    },
}
EMP
источник
Я согласен, я люблю Sentry! Я хочу иметь .Net порт этого (работал над проектами .Net в последнее время).
Громер
1
Маленькая опечатка на случай, если кто-то вырезает и вставляет: «пропогатить» вместо «размножаться» в конце.
user1228295
3
'include_html': TrueНЕ просто делает электронные письма "лучше"! Включает полный возврат, включая значения настроек и локальные переменные. Согласно документам, это проблема безопасности: docs.djangoproject.com/en/1.8/topics/logging/…
Томас,
1
Мне любопытно, нужен ли обработчик mail_admins (и django.request logger), поскольку у вас есть 'disable_existing_loggers': False и вы просто реплицируете ведение журнала django по умолчанию с этим обработчиком (и logger). Я обновлю, когда я проверю.
DylanYoung
Пожалуйста, обновите этот ответ. Из журнала изменений django1.9: стандартная конфигурация журнала Django больше не определяет регистраторы django.request и django.security.
Нарендра-Чоудхары
30

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

1) CrashLog - хороший выбор: http://code.google.com/p/django-crashlog/

2) Db-Log также является хорошим выбором: http://code.google.com/p/django-db-log/

Какая разница между двумя? Почти ничего, что я вижу, так что либо одного будет достаточно.

Я использовал оба, и они хорошо работают.

montylounge
источник
15

Прошло некоторое время с момента предоставления наиболее полезного кода EMP. Я только что реализовал это, и, пытаясь найти какую-то опцию manage.py, чтобы попытаться отследить ошибку, я получил предупреждение об устаревании о том, что в моей текущей версии Django (1.5.?) Фильтр require_debug_false теперь нужен для обработчика mail_admins.

Вот пересмотренный код:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'filters': {
         'require_debug_false': {
             '()': 'django.utils.log.RequireDebugFalse'
         }
     },
    'handlers': {
        # Include the default Django email handler for errors
        # This is what you'd get without configuring logging at all.
        'mail_admins': {
            'class': 'django.utils.log.AdminEmailHandler',
            'level': 'ERROR',
            'filters': ['require_debug_false'],
             # But the emails are plain text by default - HTML is nicer
            'include_html': True,
        },
        # Log to a text file that can be rotated by logrotate
        'logfile': {
            'class': 'logging.handlers.WatchedFileHandler',
            'filename': '/home/username/public_html/djangoprojectname/logfilename.log'
        },
    },
    'loggers': {
        # Again, default Django configuration to email unhandled exceptions
        'django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
        },
        # Might as well log any errors anywhere else in Django
        'django': {
            'handlers': ['logfile'],
            'level': 'ERROR',
            'propagate': False,
        },
        # Your own app - this assumes all your logger names start with "myapp."
        'myapp': {
            'handlers': ['logfile'],
            'level': 'DEBUG', # Or maybe INFO or WARNING
            'propagate': False
        },
    },
}
Майк О'Коннор
источник
Мне любопытно, нужен ли обработчик mail_admins (и django.request logger), поскольку у вас есть 'disable_existing_loggers': False и вы просто реплицируете ведение журнала django по умолчанию с этим обработчиком (и logger). Я обновлю, когда я проверю.
DylanYoung
1

У меня просто была досадная проблема с моим fcgiсценарием. Это произошло еще до того, как Джанго начал. Отсутствие лесозаготовок ооочень больно. В любом случае, перенаправление stderr в файл, как первое, очень помогло:

#!/home/user/env/bin/python
sys.stderr = open('/home/user/fcgi_errors', 'a')
jozxyqk
источник