Як реєструвати помилки сервера на сайтах django


175

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

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

Які рішення для ведення журналів ви б рекомендували для сайту django, який би відповідав цим простим вимогам? У мене програма працює як fcgiсервер, і я використовую веб-сервер apache як фронтенд (хоча я думаю про перехід на lighttpd).


щось із бойового майданчика: dlo.me/what-to-do-when-your-site-goes-viral
Cherian

2
Sentry для перегляду журналів: 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
        },
    },
}

Я згоден, я люблю Sentry! Я хочу мати його .Net порт (останнім часом працюю над проектами .Net).
Громер

1
Невеликий друк на випадок, якщо хтось ріже та вставляє: "пропонуйте" замість "розповсюдження" наприкінці.
користувач1228295

3
'include_html': TrueНЕ просто робить електронні листи "приємнішими"! Він включає повний прослідок, включаючи значення параметрів та локальні змінні. Згідно з документами, це питання безпеки: docs.djangoproject.com/en/1.8/topics/logging/…
Thomas

1
Мені цікаво, чи потрібен обробник mail_admins (і django.request logger), оскільки у вас є "disabled_existing_loggers": Невірно і просто реплікація журналу django за замовчуванням за допомогою цього обробника (і реєстратора). Я оновлю, коли я тестую.
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/

Яка різниця між ними? Майже нічого, що я бачу, тож і одного вистачить.

Я використовував і те, і вони добре працюють.


15

Минуло деякий час з моменту надання найбільш корисного коду EMP. Я щойно реалізував це, і, намагаючись переслідувати помилку, намагався переслідувати помилку, я отримав попередження про депресацію, що в моїй поточній версії Django (1.5.) Тепер потрібен фільтр Requ_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), оскільки у вас є "disabled_existing_loggers": Невірно і просто реплікація журналу django за замовчуванням за допомогою цього обробника (і реєстратора). Я оновлю, коли я тестую.
DylanYoung

1

У мене просто була набридлива проблема з моїм fcgiсценарієм. Це сталося ще до того, як джанго навіть почалося. Відсутність лісозаготівлі так болісно. У будь-якому випадку перенаправлення stderr до файлу як найперше допомогло дуже багато:

#!/home/user/env/bin/python
sys.stderr = open('/home/user/fcgi_errors', 'a')
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.