ロギング

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: ログメッセージを生成したリクエストオブジェクト (socket.socket) 。

django.template

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

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

django.db.backends

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

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

  • duration: SQLを実行するのにかかった時間。
  • sql: 実行されたSQL文。
  • params: SQLの呼び出しに使ったパラメータ。
  • alias: SQL 呼び出しで使用されるデータベースのエイリアス。

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

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

Changed in Django 4.2:

トランザクション管理クエリ(BEGIN, COMMIT, ROLLBACK)のログ記録のサポートが追加されました。

django.utils.autoreload

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

django.contrib.gis

GeoDjango に関連するログメッセージは、外部の地理空間ライブラリ(GEOS、GDALなど)の読み込み時や、エラーを報告する時点で様々な場所に記録されます。各 ERROR ログレコードには、発生した例外と関連するコンテキストデータが含まれます。

django.dispatch

このロガーは シグナル において使用されており、特に Signal クラス内で、接続されたレシーバへのシグナルのディスパッチ時に問題が発生した場合に報告するために使用されます。ERROR ログレコードには捕捉された例外が exc_info として含まれ、以下の追加コンテキストが加えられます。

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

django.security.*

セキュリティログは、 SuspiciousOperation および他のセキュリティ関連のエラーが発生した際にメッセージを受け取ります。セキュリティエラーの各サブタイプごとにサブロガーがあり、すべての SuspiciousOperation が含まれます。ログイベントのレベルは、例外が処理される場所によって異なります。ほとんどの発生は警告としてログされますが、WSGIハンドラーに到達した SuspiciousOperation はエラーとしてログされます。たとえば、クライアントからのリクエストに含まれるHTTP Host ヘッダーが ALLOWED_HOSTS と一致しない場合、Djangoは400のレスポンスを返し、django.security.DisallowedHost ロガーにエラーメッセージがログされます。

これらのログイベントはデフォルトで 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 は、 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 の場合にのみレコードが渡されます。

Back to Top