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

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

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

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

Ответ 1

Ну, когда DEBUG = False, Django автоматически отправит полный ответ на любую ошибку каждому человеку, указанному в параметре 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

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

Ответ 2

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
        },
    },
}

Ответ 4

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

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

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

В чем разница между этими двумя? Почти ничего, что я могу видеть, поэтому одного будет достаточно.

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

Ответ 5

Прошло некоторое время с момента подачи наиболее полезного кода 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
        },
    },
}

Ответ 6

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

#!/home/user/env/bin/python
sys.stderr = open('/home/user/fcgi_errors', 'a')