web-dev-qa-db-ja.com

Djangoサイトでサーバーエラーを記録する方法

そのため、開発で遊んでいるときに、settings.DEBUGTrueに設定するだけで、エラーが発生した場合、適切なスタックトレースとリクエスト情報で適切にフォーマットされていることがわかります。

しかし、実稼働サイトでは、DEBUG=Falseを使用し、訪問者に標準エラー500ページに、現在このバグの修正に取り組んでいる情報を表示します;)
同時に、すべての情報(スタックトレースとリクエスト情報)をサーバー上のファイルに記録する方法が欲しいので、コンソールに出力してエラースクロールを見ることができます。 1時間ごと、またはこのようなログをメールで送ってください。

Djangoサイトでは、これらの簡単な要件を満たすために、どのロギングソリューションをお勧めしますか?アプリケーションをfcgiサーバーとして実行しており、フロントエンドとしてApache Webサーバーを使用しています(lighttpdへの移行を考えていますが)。

169
kender

まあ、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

ただし、notは例外オブジェクトへのアクセスを許可するため、ミドルウェアメソッドを使用する方がはるかに簡単です。

98
James Bennett

既に述べたように、Django Sentryは良い方法ですが、適切な設定(別のWebサイトとして)には少し手間がかかります。すべてを単純なテキストファイルに記録する場合は、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
        },
    },
}
77
EMP

別の回答で言及されたDjango-db-logは、次のものに置き換えられました。

https://github.com/dcramer/Django-sentry

39
tobych

明らかにジェームズは正しいですが、データストアに例外を記録したい場合は、いくつかのオープンソースソリューションがすでに利用可能です。

1)CrashLogは良い選択です: http://code.google.com/p/Django-crashlog/

2)Db-Logも良い選択です: http://code.google.com/p/Django-db-log/

2つの違いは何ですか?私が見ることができるものはほとんどないので、どちらでも十分です。

私は両方を使用しましたが、うまく機能します。

30
montylounge

EMPが最も役立つコードを提出してからしばらく経ちました。実装したばかりで、manage.pyオプションを使用して、バグを追跡するために、現在のバージョンのDjango(1.5。? )mail_adminsハンドラーにrequire_debug_falseフィルターが必要になりました。

修正されたコードは次のとおりです。

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
        },
    },
}
13
Mike O'Connor

fcgiスクリプトに問題がありました。 Djangoが開始する前に発生しました。ロギングの欠如はとても痛いです。とにかく、stderrを最初のファイルとしてファイルにリダイレクトすることは非常に役立ちました。

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