ロギング

Django の logging モジュールは Python の 組み込み logging モジュールを継承しています。

Logging は、一般的なDjangoの django.setup() 関数の一部として設定されているため、明示的に無効にされない限り常に利用可能です。

Django のデフォルトのロギング設定

デフォルトでは、Django は Python の logging.config.dictConfig フォーマット を使用します。

デフォルトのログ記録条件

デフォルトのログ記録条件の完全なセットは以下の通りです:

DEBUGTrue のとき:

  • django ロガーは、django ヒエラルキー (django.server を除く) において、INFO レベル以上のメッセージをコンソールに送信します。

DEBUGFalse のとき:

  • django ロガーは、django ヒエラルキー (django.server を除く) において、ERROR ないし CRITICAL レベルを AdminEmailHandler に送信します。

DEBUG の値にかかわらず:

  • django.server ロガーは INFO レベル以上のメッセージをコンソールに送信します。

django.server を除く全てのロガーは、ルートの django ロガーまで、親に対してログを伝播させます。consolemail_admins ハンドラは、上述の動作を提供するためにルートロガーにアタッチされます。

Pythonのデフォルトは、レベル WARNING 以上のレコードをコンソールに送ります。

デフォルトのロギング定義

Django のデフォルトのロギング設定は、Python のデフォルトを継承しています。これは django.utils.log.DEFAULT_LOGGING として利用可能で、 django/utils/log.py で定義されています。

{
    "version": 1,
    "disable_existing_loggers": False,
    "filters": {
        "require_debug_false": {
            "()": "django.utils.log.RequireDebugFalse",
        },
        "require_debug_true": {
            "()": "django.utils.log.RequireDebugTrue",
        },
    },
    "formatters": {
        "django.server": {
            "()": "django.utils.log.ServerFormatter",
            "format": "[{server_time}] {message}",
            "style": "{",
        }
    },
    "handlers": {
        "console": {
            "level": "INFO",
            "filters": ["require_debug_true"],
            "class": "logging.StreamHandler",
        },
        "django.server": {
            "level": "INFO",
            "class": "logging.StreamHandler",
            "formatter": "django.server",
        },
        "mail_admins": {
            "level": "ERROR",
            "filters": ["require_debug_false"],
            "class": "django.utils.log.AdminEmailHandler",
        },
    },
    "loggers": {
        "django": {
            "handlers": ["console", "mail_admins"],
            "level": "INFO",
        },
        "django.server": {
            "handlers": ["django.server"],
            "level": "INFO",
            "propagate": False,
        },
    },
}

このデフォルトのロギング設定を補完または置換する方法については、ロギングを設定する を参照してください。

Django のロギング拡張

Djangoは、Web サーバー環境でのロギングの特別な要件を処理するための多数のユーティリティを提供しています。

ロガー

Djangoはいくつかの組み込みロガーを提供しています。

django

django 名前付きロガー階層 のメッセージの親ロガーです。 Djangoは、この名前を使用してメッセージを投稿しません。代わりに、以下のロガーのいずれかを使用します。

django.request

リクエストに関するログをハンドリングします。5XXレスポンスは ERROR メッセージとして送られ、 4XXレスポンスは WARNING メッセージとして送られます。 django.security ロガーに出力されたメッセージは、 django.request ロガーには送られません。

このロガーに送られるメッセージには、以下のようなコンテキストが含まれます。

  • status_code: リクエストに対するレスポンスのHTTPレスポンスコード。

  • request: ログのメッセージに対応するリクエストのオブジェクト。

django.server

runserver コマンドによって立ち上がったサーバーが受け取ったリクエストに関するログメッセージ。HTTP の 5XX レスポンスは ERROR メッセージとして送られ、 4XX レスポンスは WARNING メッセージとして送られ、その他は INFO メッセージとして送られます。

このロガーに送られるメッセージには、以下のようなコンテキストが含まれます。

  • status_code: リクエストに対するレスポンスのHTTPレスポンスコード。

  • request: The request object (a socket.socket) that generated the logging message.

django.template

テンプレートのレンダリングに関するログメッセージ。

  • コンテキストに変数が無い場合は DEBUG メッセージとして送られる。

django.db.backends

コードとデータベースの間でのやりとりに関するメッセージ。たとえば、アプリケーションから実行全ての SQL は DEBUG レベルでメッセージが送られます。

このロガーに送られるメッセージには、以下のようなコンテキストが含まれます。

  • duration: SQLを実行するのにかかった時間。

  • sql: 実行されたSQL文。

  • params: SQLの呼び出しに使ったパラメータ。

  • alias: SQL 呼び出しで使用されるデータベースのエイリアス。

パフォーマンスの観点から、 SQL ログは、ログレベルやハンドラに関わらず、 settings.DEBUG に True が設定されているときのみ有効になります。

このログには、フレームワークレベルの初期化(例: SET TIMEZONE) は含まれていません。すべてのデータベースクエリを表示したい場合は、データムベースでクエリログを有効にしてください。

django.utils.autoreload

Django 開発サーバー実行中の自動コードリロードに関連するログメッセージです。このロガーは、ソースコードファイルの変更を検出した際に INFO メッセージを生成し、ファイルシステムの検査やイベント購読プロセス中に WARNING メッセージを生成することがあります。

django.contrib.auth

Log messages related to django.contrib.auth, particularly ERROR messages are generated when a PasswordResetForm is successfully submitted but the password reset email cannot be delivered due to a mail sending exception.

django.contrib.gis

Log messages related to GeoDjango at various points: during the loading of external GeoSpatial libraries (GEOS, GDAL, etc.) and when reporting errors. Each ERROR log record includes the caught exception and relevant contextual data.

django.dispatch

This logger is used in シグナル, specifically within the Signal class, to report issues when dispatching a signal to a connected receiver. The ERROR log record includes the caught exception as exc_info and adds the following extra context:

  • receiver: レシーバの名前。

  • err: レシーバを呼び出した時に発生した例外。

django.security.*

The security loggers will receive messages on any occurrence of SuspiciousOperation and other security-related errors. There is a sub-logger for each subtype of security error, including all SuspiciousOperations. The level of the log event depends on where the exception is handled. Most occurrences are logged as a warning, while any SuspiciousOperation that reaches the WSGI handler will be logged as an error. For example, when an HTTP Host header is included in a request from a client that does not match ALLOWED_HOSTS, Django will return a 400 response, and an error message will be logged to the django.security.DisallowedHost logger.

これらのログイベントはデフォルトで django ロガーに到達し、DEBUG=False のときにはエラーイベントを管理者にメールします。SuspiciousOperation によって400レスポンスを引き起こすリクエストは django.request ロガーには記録されず、django.security ロガーにのみ記録されます。

特定のタイプの SuspiciousOperation を無視するには、以下の例に従って、その特定のロガーをオーバーライドできます:

LOGGING = {
    # ...
    "handlers": {
        "null": {
            "class": "logging.NullHandler",
        },
    },
    "loggers": {
        "django.security.DisallowedHost": {
            "handlers": ["null"],
            "propagate": False,
        },
    },
    # ...
}

SuspiciousOperation に基づかない他の django.security ロガーには、以下があります:

django.db.backends.schema

スキーマの変更中に実行されるSQLクエリを、 マイグレーションフレームワーク によってログ記録します。ただし、 RunPython によって実行されるクエリはログされません。このロガーへのメッセージには、 paramssql が追加のコンテキストとして含まれます(ただし、 django.db.backends とは異なり、実行時間は含まれません)。これらの値の意味については、 django.db.backends で説明されている内容と同じです。

django.contrib.sessions

セッションフレームワーク に関連するログメッセージです。

ハンドラ

Django は、 Pythonのモジュールによって提供されるもの に加えて、1つのログハンドラを提供しています。

class AdminEmailHandler(include_html=False, email_backend=None, reporter_class=None)[ソース]

このハンドラは、受け取ったログメッセージごとにサイトの ADMINS に電子メールを送信します。

ログレコードに request 属性が含まれている場合、リクエストの詳細がメールに含まれます。クライアントの IP アドレスが INTERNAL_IPS 設定にある場合、メールの件名に "internal IP" というフレーズが含まれます。そうでない場合は "EXTERNAL IP" が含まれます。

ログレコードにスタックトレース情報が含まれている場合、そのスタックトレースは電子メールに含まれます。

AdminEmailHandlerinclude_html 引数は、 DEBUGTrue の場合に生成されるデバッグウェブページの内容を含む HTML 添付ファイルを traceback メールに含めるかどうかを制御するために使用されます。この値を設定するには、django.utils.log.AdminEmailHandler のハンドラ定義に含めます。以下のようになります:

"handlers": {
    "mail_admins": {
        "level": "ERROR",
        "class": "django.utils.log.AdminEmailHandler",
        "include_html": True,
    },
}

AdminEmailHandler を使用する際は、 ログのセキュリティ上の注意点 に注意してください。

AdminEmailHandleremail_backend 引数を設定することで、ハンドラーが使用している メールバックエンド を以下のように上書きできます:

"handlers": {
    "mail_admins": {
        "level": "ERROR",
        "class": "django.utils.log.AdminEmailHandler",
        "email_backend": "django.core.mail.backends.filebased.EmailBackend",
    },
}

デフォルトでは、 EMAIL_BACKEND で指定されたメールバックエンドのインスタンスが使用されます。

AdminEmailHandlerreporter_class 引数では、メール本文で送信されるトレースバックテキストをカスタマイズするために django.views.debug.ExceptionReporter サブクラスを提供できます。使用したいクラスへの文字列インポートパスをこのように指定します:

"handlers": {
    "mail_admins": {
        "level": "ERROR",
        "class": "django.utils.log.AdminEmailHandler",
        "include_html": True,
        "reporter_class": "somepackage.error_reporter.CustomErrorReporter",
    },
}
send_mail(subject, message, *args, **kwargs)[ソース]

管理ユーザーにメールを送信します。この動作をカスタマイズするためには、 AdminEmailHandler クラスをサブクラス化して、このメソッドをオーバーライドできます。

フィルタ

Djangoは、Pythonのロギングモジュールによって提供されるフィルタに加えて、いくつかのログフィルタを提供しています。

class CallbackFilter(callback)[ソース]

このフィルタは、(1 つの引数、ログを行うレコード) を受け入れるコールバック関数を受け入れ、フィルタを通過する各レコードに対してその関数をコールします。コールバックが False を返す場合、そのレコードの処理は進みません。

例えば、管理者メールから(ユーザーがアップロードをキャンセルした時に発生する) UnreadablePostError をフィルタリングするために、フィルタ関数を作成します。

from django.http import UnreadablePostError


def skip_unreadable_post(record):
    if record.exc_info:
        exc_type, exc_value = record.exc_info[:2]
        if isinstance(exc_value, UnreadablePostError):
            return False
    return True

次に、ログ設定にそれを追加します:

LOGGING = {
    # ...
    "filters": {
        "skip_unreadable_posts": {
            "()": "django.utils.log.CallbackFilter",
            "callback": skip_unreadable_post,
        },
    },
    "handlers": {
        "mail_admins": {
            "level": "ERROR",
            "filters": ["skip_unreadable_posts"],
            "class": "django.utils.log.AdminEmailHandler",
        },
    },
    # ...
}
class RequireDebugFalse[ソース]

このフィルタは、settings.DEBUG が False の時のみ、レコードを通過させます。

このフィルタは、デフォルトの LOGGING 設定で以下のように使用され、 DEBUGFalse のときのみ AdminEmailHandler がエラーメールを管理者に送信するようにします:

LOGGING = {
    # ...
    "filters": {
        "require_debug_false": {
            "()": "django.utils.log.RequireDebugFalse",
        },
    },
    "handlers": {
        "mail_admins": {
            "level": "ERROR",
            "filters": ["require_debug_false"],
            "class": "django.utils.log.AdminEmailHandler",
        },
    },
    # ...
}
class RequireDebugTrue[ソース]

このフィルタは RequireDebugFalse に似ていますが、DEBUGTrue の場合にのみレコードが渡されます。