エラーレポートの管理Link to this heading

サイトを公開している場合、DEBUG 設定は常にオフにしておかなければなりません。これにより、サーバー動作は高速になり、エラーページによって明らかになるアプリケーションの詳細が悪意あるユーザーに漏れるのを防ぎます。

しかし、 DEBUGFalse にセットして実行すると、サイトによって生成されるエラーが見られなくなります――表示されるのは万人向けのエラーページだけです。そこで、本番サイトで起きたエラーを追跡するために、Django ではこれらのエラーに関する詳細なレポートを作成するように設定できます。

E メールのレポートLink to this heading

サーバーエラーLink to this heading

DEBUGFalse であるとき、コードがハンドリングされない例外を起こして内部サーバーエラーが起きると (厳密には、500 以上の HTTP ステータスコードを持つ全てのレスポンスが返ってくると)、Django は ADMINS 設定のリストに含まれるユーザーにメールを送信します。これにより、管理者はすぐにエラーの通知を受け取ることができます。メールには、ADMINS はエラーの説明、Python のトレースバック全体、エラーを引き起こした HTTP リクエストの詳細について書かれています。

By default, Django will send email from root@localhost. However, some mail providers reject all email from this address. To use a different sender address, modify the SERVER_EMAIL setting.

この動作を有効にするには、受信者のメールアドレスを ADMINS 設定に含めます。

404 エラーLink to this heading

Django は、リンク切れに関するエラー (404 "page not found" エラー) をメールで送信するように設定することもできます。Django は以下の場合に 404 エラーに関するメールを送ります:

これらの条件が満たされると、Django はあなたのコードが 404 を発生させ、そのリクエストがリファラを持っている場合、 MANAGERS 設定にリストされているユーザにメールを送ります。リファラを持たない 404 にはわざわざメールを送りません。それは大抵、壊れた URL を入力したユーザか、壊れた Web ボットです。また、リファラがリクエストされた URL と同じ場合の 404 も無視します。

特定の 404 を報告しないように Django に指示するには、 IGNORABLE_404_URLS 設定をいじります。これはコンパイルされた正規表現オブジェクトのリストでなければなりません。例えば:

Code
import re

IGNORABLE_404_URLS = [
    re.compile(r"\.(php|cgi)$"),
    re.compile(r"^/phpmyadmin/"),
]

この例では、 .php または .cgi で終わる URL への 404 は報告されません。また、 /phpmyadmin/ で始まるURLも報告されません。

以下は、ブラウザやクローラがよくリクエストする従来の URL を除外する方法の例です:

Code
import re

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

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

django.middleware.common.BrokenLinkEmailsMiddleware の動作をさらにカスタマイズしたい場合(例えば、ウェブクローラからのリクエストを無視したい場合など)は、サブクラスを作成し、そのメソッドをオーバーライドしてください。

エラーレポートをフィルタリングするLink to this heading

機密情報のフィルタリングLink to this heading

エラーレポートはエラーのデバッグにとても役立つので、通常は、エラーに関する関連情報をできるだけ多く記録しておくと便利です。例えば、デフォルトでは Django は発生した例外の full traceback や、各 traceback frame のローカル変数、 HttpRequest属性 を記録します。

しかし、例えばユーザのパスワードやクレジットカード番号のように、ある種の情報は機密性が高すぎるため、記録するのが適切でない場合があります。そこで Django では、 DEBUG ドキュメントで説明されているように、機密性が高そうな設定をフィルタリングすることに加えて、本番環境 (つまり、 DEBUGFalse に設定されている場合) でエラーレポートからフィルタリングされる情報を制御するのに役立つ関数デコレータを提供しています。 sensitive_variables()sensitive_post_parameters() です。

sensitive_variables(*variables)Link to this definition

コード内の関数(ビューまたは通常のコールバック)が機密情報を含む可能性のあるローカル変数を使用している場合、 sensitive_variables デコレータを使用することで、それらの変数の値がエラーレポートに含まれないようにすることができます:

Code
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
    ...

上記の例では、 userpwcc の値は非表示になり、エラーレポートではアスタリスク (*******) に置き換えられますが、 name 変数の値は公開されます。

関数のすべてのローカル変数をエラーログから徹底的に隠す場合は、引数なしで sensitive_variables デコレーターを使います:

Code
@sensitive_variables()
def my_function(): ...
sensitive_post_parameters(*parameters)Link to this definition

If one of your views receives an HttpRequest object with POST parameters susceptible to contain sensitive information, you may prevent the values of those parameters from being included in the error reports using the sensitive_post_parameters decorator:

Code
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"],
    )
    ...

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

エラーレポートでリクエストの全てのPOSTパラメータを徹底的に隠す場合は、 引数なしで sensitive_post_parameters デコレータを使います:

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

特定の django.contrib.auth.views のビュー (auth admin 内の login, password_reset_confirm, password_change, auth admin の add_viewuser_change_password) のエラーレポートから、すべての POST パラメータが徹底的にフィルタされ、ユーザパスワードのような機密情報の漏洩を防ぎます。

カスタムエラーレポートLink to this heading

sensitive_variables()sensitive_post_parameters() がすることは、それぞれ、装飾された関数にセンシティブな変数名をアノテートし、HttpRequest オブジェクトにセンシティブな POST パラメータ名をアノテートするだけです。実際のフィルタリングは Django のデフォルトのエラーレポートフィルタ ( django.views.debug.SafeExceptionReporterFilter ) で行われます。このフィルタはデコレータのアノテーションを使い、エラーレポートが生成される際に、対応する値をアスタリスク (*******) に置き換えます。このデフォルトの動作を上書きしたり、サイト全体でカスタマイズしたい場合は、独自のフィルタクラスを定義し、 DEFAULT_EXCEPTION_REPORTER_FILTER 設定でそれを使うように Django に指示する必要があります:

Code
DEFAULT_EXCEPTION_REPORTER_FILTER = "path.to.your.CustomExceptionReporterFilter"

また、 HttpRequestexception_reporter_filter 属性を指定することで、任意のビューで使用するフィルタをより細かく制御できます:

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

カスタムフィルタクラスは django.views.debug.SafeExceptionReporterFilter を継承し、以下の属性とメソッドをオーバーライドする必要があります:

class SafeExceptionReporterFilterLink to this definition
cleansed_substituteLink to this definition

センシティブな値を置換する文字列値。デフォルトでは、センシティブな変数の値をアスタリスク (*******) で置き換えます。

hidden_settingsLink to this definition

センシティブな設定や request.META にマッチする正規表現オブジェクト。デフォルトでは下記です:

Code
import re

re.compile(r"API|AUTH|TOKEN|KEY|SECRET|PASS|SIGNATURE|HTTP_COOKIE", flags=re.IGNORECASE)
is_active(request)Link to this definition

get_post_parameters()get_traceback_frame_variables() のフィルタリングを有効にする場合は True を返します。デフォルトでは DEBUGFalse の場合に有効になります。 DEBUG のドキュメントにあるように、センシティブな request.META の値は常に、センシティブな設定値とともにフィルタリングされることに注意してください。

get_post_parameters(request)Link to this definition

フィルタリングされた POST パラメータの辞書を返します。センシティブな値は cleansed_substitute で置換されます。

get_traceback_frame_variables(request, tb_frame)Link to this definition

与えられたトレースバックフレームのローカル変数のフィルタリングされた辞書を返します。センシティブな値は cleansed_substitute で置き換えられます。

フィルタリングの他にエラーレポートをカスタマイズする必要がある場合は、 DEFAULT_EXCEPTION_REPORTER 設定を定義することでカスタムエラーレポータークラスを指定できます:

Code
DEFAULT_EXCEPTION_REPORTER = "path.to.your.CustomExceptionReporter"

例外レポーターは例外レポートデータをコンパイルし、テキストまたはHTMLとして適切にフォーマットする責任があります。(例外報告レポーターは、例外レポートデータを作成する際に DEFAULT_EXCEPTION_REPORTER_FILTER を使用します)。

カスタムレポータークラスは django.views.debug.ExceptionReporter を継承する必要があります。

class ExceptionReporterLink to this definition
html_template_pathLink to this definition

例外の HTML 表現をレンダリングするテンプレートへの絶対ファイルシステムパスを表す pathlib.Path を返すプロパティです。デフォルトは Django が提供するテンプレートです。

text_template_pathLink to this definition

pathlib.Path を返すプロパティで、例外のプレーンテキスト表現をレンダリングするテンプレー トへのファイルシステムの絶対パスを表します。デフォルトは Django が提供するテンプレートです。

get_traceback_data()Link to this definition

トレースバック情報を含む辞書を返します。

これは、例えば例外レポートをカスタマイズするための主な拡張ポイントです。例えば下記のようにします:

Code
from django.views.debug import ExceptionReporter


class CustomExceptionReporter(ExceptionReporter):
    def get_traceback_data(self):
        data = super().get_traceback_data()
        # ... remove/add something here ...
        return data
get_traceback_html()Link to this definition

例外レポートの HTML 版を返します。

デバッグ 500 HTTP エラー・ページの HTML 版に使用されます。

get_traceback_text()Link to this definition

例外レポートのプレーンテキスト版を返します。

デバッグ 500 HTTP エラーページおよび E メールレポートのプレーンテキスト版に使用されます。

フィルタクラスと同様に、 HttpRequestexception_reporter_class 属性を指定することで、任意のビューで使用する例外レポータークラスを制御できます:

Code
def my_view(request):
    if request.user.is_authenticated:
        request.exception_reporter_class = CustomExceptionReporter()
    ...