エラー通知

revision-up-to:17812 (1.4)

サイトを公開しているときには、 DEBUG を常に切りましょう。 DEBUG を切ると、サーバの動作は軽くなり、エラーページを介して悪意 あるユーザにアプリケーションの詳細が漏れてしまうのを防げます。

その代わり、 DEBUGFalse にすると、サイト上で発生したエラー を一切表示できません。ユーザはみな、公開用に作られたエラーページを見るだけ です。実運用のサイトで発生したエラーを追跡したい場合のために、 Django はエ ラーの詳細について通知するように設定できます。

メールでの通知

サーバのエラー

DEBUGFalse にすると、コード内で例外が送出され、その例外 が捕捉されず、結果的に 500 エラーになった場合に、 Django は ADMINS 設定にリストされている全てのユーザにメールを送信します。 これは、管理者が何らかのエラーにすぐに気づけるようにするためで す。 ADMINS はエラーの説明文と、 Python トレースバックと、エラー を引き起こした HTTP リクエストの詳細情報を受け取ります。

Note

メールを送るためにはメールサーバへの接続方法についていくつかの設定をする ことが必要です。最低限、 EMAIL_HOST とおそらく EMAIL_HOST_USEREMAIL_HOST_PASSWORD が必要でし ょう。他の設定もメールサーバの設定によっては必要になるかもしれません。 メール関連の全ての設定のリストは Django 設定ドキュメント をあたってください。

デフォルトの設定では、 Django はメールの送信元に root@localhost を使います。 メールを処理するプロバイダの中には、 root@localhost から送信されたメールを 全て拒否するよう設定しているものがあります。送信者アドレスを変更したければ、 SERVER_EMAIL を変更してください。

メール通知機能を無効にするには、 ADMINS 設定から全てのユーザを削 除してください。

See also

Django 1.3 で新たに登場しました: リリースノートを参照してください

サーバエラーのメール通知はロギングフレームワークを使っているので、 ロギング設定のカスタマイズ によって動作を変更でき ます。

404 エラー

Django は、サイトのリンクが切れている (404 “page not found” エラーが発生す る) 時にメールを送信するよう設定できます。 404 エラーメールは、以下の条件下 で送信されます:

これらの条件が揃っていると、コード中で 404 例外が生じ、かつリクエストにリファ ラが設定されているときに、 Django は MANAGERS 設定に登録された全 てのユーザにメールを送信します (リファラ付きが条件なのは、リファラのないリ クエストに対する404 エラーで管理者を煩わせないためです)。

IGNORABLE_404_URLS を使えば、特定の 404 に対するレポート送信を抑 制できます。例えば:

import re
IGNORABLE_404_URLS = (
    re.compile(r'\.(php|cgi)$'),
    re.compile(r'^/phpmyadmin/'),
)

のようにすると、 URL が .php.cgi で終わるような URL や /phpmyadmin/ で始まる URL に対する 404 は報告 されません

以下は、ブラウザやクローラがよくリクエストする慣習的な URL を除外する例です:

import re
IGNORABLE_404_URLS = (
    re.compile(r'^/apple-touch-icon.*\.png$'),
    re.compile(r'^/favicon\.ico$'),
    re.compile(r'^/robots\.txt$'),
)

(正規表現のため、ピリオドの前にエスケープのためのバックスラッシュを置いている ことに注意してください)

この機能を無効にしたければ、 SEND_BROKEN_LINK_EMAILSFalse に設定してください。

See also

Django 1.3 で新たに登場しました: リリースノートを参照してください

404 エラーはロギングフレームワークを使って記録されます。デフォルトではこれ らのログレコードは無視されますが、ハンドラを書き、 ロギングの設定 を適切に行うことで、エラーレポート に使うことができます。

See also

Django 1.4 で変更されました: リリースノートを参照してください

URL を通知対象外にするために、以前は 2 つの設定 IGNORABLE_404_STARTSIGNORABLE_404_ENDS が使われて いました。これらは IGNORABLE_404_URLS に置き換えられました。

エラー通知のフィルタリング

Django 1.4 で新たに登場しました: リリースノートを参照してください

センシティブ(機微)な情報をフィルタリングする

エラー通知はエラーをデバッグするのに実に役立ちます。一般的に、エラーに関係する 情報は可能な限り多く記録しておくと便利です。例えば、例外が起こった時、 Django はデフォルトで フルトレースバック と、それぞれの トレースバックフレーム のローカル変数、 HttpRequest属性 を記録します。

しかし、時にはある種の情報はセンシティブすぎて、追跡するのが適切ではないことが あります。例えば、ユーザーのパスワードやクレジットカードナンバーがそうです。そ のため Django は一揃いの関数デコレータ sensitive_variables()sensitive_post_parameters().を提供しています。 これらは運用環境 (つまり DEBUGFalse にセットされた環境) でど の情報をエラーレポートから除外すべきかを制御するのに役立ちます。

sensitive_variables(*variables)

もしあなたのコードの関数 (ビューや他の通常のコールバック) がセンシティブな 情報を含みうる変数を使っているなら、 sensitive_variables デコレータを 使うことで、それらの変数の値がエラーレポートに含まれることを避けることがで きます:

from django.views.decorators.debug import sensitive_variables

@sensitive_variables('user', 'pw', 'cc')
def process_info(user):
    pw = user.pass_word
    cc = user.credit_card_number
    name = user.name
    ...

上の例で、 user, pw, cc 変数はエラーレポートでは隠され、アスタ リスク (**********) に置き換えられます。一方、 name 変数の値は表示さ れます。

ある関数の全てのローカル変数を、一律にエラーログから隠すには、 sensitive_variables デコレータに何も引数を渡さないようにします:

@sensitive_variables()
def my_function():
    ...
sensitive_post_parameters(*parameters)

もしあなたのビューがセンシティブな情報を含みうる POST パラメータ を持つ HttpRequest オブ ジェクトを受け取るなら、 sensitive_post_parameters デコレータを使うこ とでそういったパラメータの値がエラーレポートに含まれることを防ぐことができ ます:

from django.views.decorators.debug import sensitive_post_parameters

@sensitive_post_parameters('pass_word', 'credit_card_number')
def record_user_profile(request):
    UserProfile.create(user=request.user,
                       password=request.POST['pass_word'],
                       credit_card=request.POST['credit_card_number'],
                       name=request.POST['name'])
    ...

上の例では、 POST パラメータの pass_wordcredit_card_number の 値がエラーレポート内のリクエストの表現では隠され、アスタリスク (**********) で置き換えられます。一方、 name パラメータの値は開示さ れます。

あるリクエストの全ての POST パラメータを、一律にエラーレポートから隠すに は、 sensitive_post_variables デコレータに何も引数を渡さないようにしま す:

@sensitive_post_parameters()
def my_view(request):
    ...

Note

Django 1.4 で変更されました: リリースノートを参照してください

バージョン 1.4 以降、ユーザーパスワードのようなセンシティブな情報が漏れる のを防ぐために、特定の contrib.views.auth のビュー (login, password_reset_confirm, password_change および auth admin の add_viewuser_change_password) のエラーレポートから、全ての POST パラメータが一律に除外されるようになりました。

カスタムエラー通知

sensitive_variables()sensitive_post_parameters() が行っている のは、それぞれ、エラーが起こった時のレポートからセンシティブな情報が除外される ように、デコレートした関数をセンシティブな変数名で注釈づけておくことと、 HttpRequest オブジェクトをセンシティブな POST パラメータの名前で注釈づける ことです。実際のフィルタリングは Django のデフォルトのエラー通知フィルタ django.views.debug.SafeExceptionReporterFilter で行われます。このフィ ルタは、エラーレポートが生成される時、デコレータによる注釈に対応する値をアスタ リスク (**********) で置換します。もし、このデフォルトの動作をサイト全体で上 書きしたい、またはカスタマイズしたいなら、自分自身のフィルタクラスを定義し、 DEFAULT_EXCEPTION_REPORTER_FILTER 設定を通じて Django にそれを使う よう指示しなければなりません:

DEFAULT_EXCEPTION_REPORTER_FILTER = 'path.to.your.CustomExceptionReporterFilter'

あるいは HttpRequestexception_reporter_filter 属性にフィルタを設定 することで、任意のビューで使うフィルタをもっと細かく制御できます:

def my_view(request):
    if request.user.is_authenticated():
        request.exception_reporter_filter = CustomExceptionReporterFilter()
    ...

カスタムフィルタは django.views.debug.SafeExceptionReporterFilter を 継承しなければならず、以下のメソッドをオーバーライドできます。

class django.views.debug.SafeExceptionReporterFilter
SafeExceptionReporterFilter.is_active(self, request)

他のメソッドで実行されるフィルタリングを有効化するなら True を返しま す。デフォルトでは、 DEBUGFalse の時にフィルタが有効に なります。

SafeExceptionReporterFilter.get_request_repr(self, request)

リクエストオブジェクトの文字列表現を返します。つまり、その値は repr(request) によって返される値になるでしょう。ただし、 SafeExceptionReporterFilter.get_post_parameters() メソッドによって取 得される POST パラメータのフィルタされた辞書を使います。

SafeExceptionReporterFilter.get_post_parameters(self, request)

POST パラメータのフィルタされた辞書を返します。デフォルトでは、センシティ ブなパラメータの値をアスタリスク (**********) によって置き換えます。

SafeExceptionReporterFilter.get_traceback_frame_variables(self, request, tb_frame)

トレースバックフレームによって与えられたローカル変数の、フィルタされた辞書 を返します。デフォルトでは、センシティブなパラメータの値をアスタリスク (**********) によって置き換えます。

See also

自作の 例外ミドルウェア を書けば、エラー レポートを自作できます。エラー処理をカスタマイズしたければ、 Django 組 み込みのエラー処理をエミュレートして、 DEBUGFalse の ときだけ、レポートやログ記録を行うとよいでしょう。