エラー報告—Djangoドキュメント

提供:Dev Guides
< DjangoDjango/docs/3.2.x/howto/error-reporting
移動先:案内検索

エラー報告

公開サイトを運営しているときは、常に:setting: `DEBUG` 設定をオフにする必要があります。 これにより、サーバーの実行速度が大幅に向上し、悪意のあるユーザーがエラーページで明らかになる可能性のあるアプリケーションの詳細を見ることができなくなります。

ただし、:setting: `DEBUG`Falseに設定して実行すると、サイトで生成されたエラーが表示されることはありません。代わりに、公開エラーページが表示されます。 デプロイされたサイトで発生するエラーを追跡する必要があるため、Djangoは、それらのエラーに関する詳細を含むレポートを作成するように構成できます。

メールレポート

サーバーエラー

:setting: `DEBUG`Falseの場合、コードで未処理の例外が発生するたびに、Djangoは:setting:` ADMINS` 設定にリストされているユーザーにメールを送信します。結果として内部サーバーエラーが発生します(厳密に言えば、HTTPステータスコードが500以上の応答の場合)。 これにより、管理者はエラーを即座に通知できます。 :setting: `ADMINS` は、エラーの説明、完全なPythonトレースバック、およびエラーの原因となったHTTPリクエストの詳細を取得します。

ノート

メールを送信するために、Djangoはメールサーバーへの接続方法を指示するいくつかの設定を必要とします。 少なくとも、:setting: `EMAIL_HOST` と、場合によっては:setting:` EMAIL_HOST_USER`:setting: `EMAIL_HOST_PASSWORD` を指定する必要があります。ただし、メールサーバーの構成によっては、他の設定も必要になる場合があります。 メール関連の設定の完全なリストについては、 Django設定ドキュメントを参照してください。


デフォルトでは、Djangoは root @ localhost からメールを送信します。 ただし、一部のメールプロバイダーは、このアドレスからのすべての電子メールを拒否します。 別の送信者アドレスを使用するには、:setting: `SERVER_EMAIL` 設定を変更します。

この動作を有効にするには、受信者の電子メールアドレスを:setting: `ADMINS` 設定に設定します。

も参照してください

サーバーエラーメールはログフレームワークを使用して送信されるため、ログ構成をカスタマイズすることでこの動作をカスタマイズできます。


404エラー

Djangoは、リンク切れに関するエラー(404「ページが見つかりません」エラー)を電子メールで送信するように構成することもできます。 Djangoは、次の場合に404エラーに関するメールを送信します。

これらの条件が満たされると、コードで404が発生し、リクエストにリファラーが含まれるたびに、Djangoは:setting: `MANAGERS` 設定にリストされているユーザーにメールを送信します。 リファラーのない404については、わざわざメールを送信する必要はありません。通常、壊れたURLや壊れたWebボットを入力する人です。 また、リファラーが要求されたURLと等しい場合、この動作は壊れたWebボットからのものであるため、404を無視します。

ノート

BrokenLinkEmailsMiddleware は、 LocaleMiddlewareFlatpageFallbackMiddleware などの404エラーをインターセプトする他のミドルウェアの前に表示される必要があります。 :setting: `MIDDLEWARE` 設定の上部に配置します。


:setting: `IGNORABLE_404_URLS` 設定を微調整することで、特定の404のレポートを停止するようにDjangoに指示できます。 コンパイルされた正規表現オブジェクトのリストである必要があります。 例えば:

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

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

次の例は、ブラウザとクローラーが頻繁に要求する従来のURLを除外する方法を示しています。

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 の動作をさらにカスタマイズする場合(たとえば、Webクローラーからの要求を無視する場合)、サブクラス化してメソッドをオーバーライドする必要があります。

も参照してください

404エラーは、ロギングフレームワークを使用してログに記録されます。 デフォルトでは、これらのログレコードは無視されますが、ハンドラーを記述し、ロギングを適切に構成することで、エラー報告に使用できます。


エラーレポートのフィルタリング

警告

機密データのフィルタリングは難しい問題であり、機密データがエラーレポートに漏れないことを保証することはほぼ不可能です。 したがって、エラーレポートは、信頼できるチームメンバーのみが利用できるようにする必要があり、暗号化されていないエラーレポートをインターネット経由(電子メールなど)で送信しないようにする必要があります。


機密情報のフィルタリング

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

ただし、ユーザーのパスワードやクレジットカード番号など、特定の種類の情報は機密性が高すぎるため、追跡するのに適切でない場合があります。 そのため、:setting: `DEBUG` のドキュメントで説明されているように機密性が高いと思われる設定を除外することに加えて、Djangoは、エラーレポートから除外する情報を制御するのに役立つ一連の関数デコレータを提供します。実稼働環境(つまり、:setting: `DEBUG`Falseに設定されている場合): sensitive_variables()および sensitive_post_parameters()[X409X ]。

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

上記の例では、userpw、およびcc変数の値は非表示になり、エラーレポートでは星(**********)に置き換えられます。一方、name変数の値は開示されます。

関数のすべてのローカル変数をエラーログから体系的に非表示にするには、sensitive_variablesデコレータに引数を指定しないでください。

@sensitive_variables()
def my_function():
    ...

複数のデコレータを使用する場合

非表示にする変数が関数の引数でもある場合(例: 次の例では「user」)。decorated関数に複数のデコレータがある場合は、必ず@sensitive_variablesをデコレータチェーンの一番上に配置してください。 このようにして、他のデコレータを通過するときに関数の引数も非表示にします。

@sensitive_variables('user', 'pw', 'cc')
@some_decorator
@another_decorator
def process_info(user):
    ...
sensitive_post_parameters(*parameters)

ビューの1つが機密情報を含む可能性のある 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'],
    )
    ...

上記の例では、pass_wordおよびcredit_card_number POSTパラメーターの値は非表示になり、エラーレポート内のリクエストの表現では星(**********)に置き換えられます。 nameパラメータの値が開示されます。

エラーレポートでリクエストのすべてのPOSTパラメータを体系的に非表示にするには、sensitive_post_parametersデコレータに引数を指定しないでください。

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

すべてのPOSTパラメーターは、特定の django.contrib.auth.views ビュー(loginpassword_reset_confirmpassword_change、および[ auth adminのadd_viewおよびuser_change_password)は、ユーザーパスワードなどの機密情報の漏洩を防ぎます。


カスタムエラーレポート

すべての sensitive_variables()および sensitive_post_parameters()は、それぞれ、装飾された関数に機密変数の名前で注釈を付け、HttpRequestオブジェクトに機密の名前で注釈を付けます。 POSTパラメータ。これにより、エラーが発生したときに、この機密情報を後でレポートから除外できます。 実際のフィルタリングは、Djangoのデフォルトのエラーレポーターフィルター django.views.debug.SafeExceptionReporterFilter によって行われます。 このフィルターは、エラーレポートが生成されるときに、デコレーターの注釈を使用して、対応する値を星(**********)に置き換えます。 サイト全体でこのデフォルトの動作をオーバーライドまたはカスタマイズする場合は、独自のフィルタークラスを定義し、:setting: `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 SafeExceptionReporterFilter
cleansed_substitute

バージョン3.1の新機能。

機密値を置き換える文字列値。 デフォルトでは、機密変数の値が星(**********)に置き換えられます。

hidden_settings

バージョン3.1の新機能。

機密と見なされる設定とrequest.META値を照合するために使用されるコンパイル済み正規表現オブジェクト。 デフォルトでは次と同等です。

import re

re.compile(r'API|TOKEN|KEY|SECRET|PASS|SIGNATURE', flags=re.IGNORECASE)
is_active(request)

Trueを返し、 get_post_parameters()および get_traceback_frame_variables()のフィルタリングをアクティブにします。 :setting: `DEBUG`Falseの場合、デフォルトでフィルターがアクティブになります。 :setting: `DEBUG` のドキュメントで説明されているように、機密性の高いrequest.META値は、常に機密性の高い設定値とともにフィルタリングされることに注意してください。

get_post_parameters(request)

POSTパラメータのフィルタリングされたディクショナリを返します。 機密値は cleansed_substitute に置き換えられます。

get_traceback_frame_variables(request, tb_frame)

指定されたトレースバックフレームのローカル変数のフィルタリングされたディクショナリを返します。 機密値は cleansed_substitute に置き換えられます。

バージョン3.1の新機能。


フィルタリング以外のエラーレポートをカスタマイズする必要がある場合は、:setting: `DEFAULT_EXCEPTION_REPORTER` 設定を定義して、カスタムエラーレポータークラスを指定できます。

DEFAULT_EXCEPTION_REPORTER = 'path.to.your.CustomExceptionReporter'

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

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

class ExceptionReporter
html_template_path

バージョン3.2の新機能。

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

text_template_path

バージョン3.2の新機能。

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

get_traceback_data()

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

これは、例外レポートをカスタマイズするための主要な拡張ポイントです。次に例を示します。

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()

例外レポートのHTMLバージョンを返します。

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

get_traceback_text()

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

プレーンテキストバージョンのdebug500HTTPエラーページおよび電子メールレポートに使用されます。

フィルタクラスと同様に、HttpRequestexception_reporter_class属性を設定することにより、特定のビュー内で使用する例外レポータークラスを制御できます。

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

も参照してください

例外ミドルウェアのカスタムピースを作成して、カスタムエラーレポートを設定することもできます。 カスタムエラー処理を作成する場合は、Djangoの組み込みエラー処理をエミュレートし、:setting: `DEBUG`Falseの場合にのみエラーを報告/ログ記録することをお勧めします。