ロギングの設定と利用Link to this heading

Django はそのままで動作する デフォルトのロギング設定 を持っており、すぐに拡張可能です。

基本的なロギング呼び出しを作成するLink to this heading

ログメッセージをコード内から送信するには、コードにロギングの呼び出しを書く必要があります。

First, import the Python logging library, and then obtain a logger instance with logging.getLogger(). Provide the getLogger() method with a name to identify it and the records it emits. A good option is to use __name__ (see ロガーの名前空間を使う below for more on this) which will provide the name of the current Python module as a dotted path:

Code
import logging

logger = logging.getLogger(__name__)

この宣言はモジュール・レベルで行うのがよいとされています。

そして、ビューなどの関数内で、logger にレコードを送信します。

Code
def some_view(request):
    ...
    if some_risky_state:
        logger.warning("Platform is running at risk")

When this code is executed, a LogRecord containing that message will be sent to the logger. If you're using Django's default logging configuration, the message will appear in the console.

上の例で使われている WARNING レベルは、いくつかある ログの重大度レベル: DEBUG, INFO, WARNING, ERROR, CRITICAL の一つです。したがって、別の例は次のようになります。

Code
logger.critical("Payment system is not responding")

ロギングの設定をカスタマイズするLink to this heading

Djangoのロギング設定は初期状態で動作しますが、追加の設定を行うことで、ログを様々な宛先(ログファイル、外部サービス、メールなど)に送信するのを正確にコントロールできます。

以下のものを設定できます。

  • どのレコードがどのハンドラに送られるかを決定するためのロガーマッピング

  • 受け取ったレコードをどう処理するかを決めるハンドラー

  • レコードの転送をさらにコントロールし、レコードをその場で変更することもできるフィルタ

  • LogRecord オブジェクトを、人間や他のシステムで利用できるように文字列や他の形式に変換するためのフォーマッタ

ロギングの設定には様々な方法があります。Django では、 LOGGING 設定が最もよく使われます。この設定は dictConfig フォーマット を使い、 デフォルトのロギング設定 を拡張します。

カスタム設定が Django のデフォルトとどのようにマージされるかについては ロギングを設定する を参照してください。

その他のロギングの設定方法の詳細については Python logging documentation を参照してください。簡単にするために、このドキュメントでは LOGGING 設定による設定のみを考えます。

ロギングの基本的な設定Link to this heading

ロギングを設定する場合、以下のようにします。

LOGGING 辞書を作成するLink to this heading

settings.py に以下を追加します:

Code
LOGGING = {
    "version": 1,  # the dictConfig format version
    "disable_existing_loggers": False,  # retain the default loggers
}

ほとんどの場合、 disable_existing_loggersFalse に設定することで、デフォルトのロギング設定を保持し、拡張できます。

ハンドラを設定するLink to this heading

この例では、Python の FileHandler を使って、レベル DEBUG 以上のログを (プロジェクトルート内の) general.log ファイルに保存する file という名前のハンドラを設定します:

Python
LOGGING = {
    # ...
    "handlers": {
        "file": {
            "class": "logging.FileHandler",
            "filename": "general.log",
        },
    },
}

Different handler classes take different configuration options. For more information on available handler classes, see the AdminEmailHandler provided by Django and the various handler classes provided by Python.

ログレベルはハンドラで設定することもできます(デフォルトでは、ハンドラはすべてのレベルのログメッセージを受け取ります)。上の例を使うと、次のように書けます:

Python
{
    "class": "logging.FileHandler",
    "filename": "general.log",
    "level": "DEBUG",
}

これで、レベル DEBUG 以上のレコードだけを受け付けるようにハンドラを設定できます。

ロガーマッピングを設定するLink to this heading

このハンドラにレコードを送信するには、ロガーマッピングをそのハンドラを使うように設定します。例えば:

Python
LOGGING = {
    # ...
    "loggers": {
        "": {
            "level": "DEBUG",
            "handlers": ["file"],
        },
    },
}

マッピングの名前はどのログレコードを処理するかを決定します。この設定 ("") は 無名 です。つまり、 すべての ロガーからのレコードを処理します(レコードを処理するロガーを決定するためにマッピング名を使用する方法については、以下の ロガーの名前空間を使う を参照してください)。

これは DEBUG レベル以上のメッセージを file というハンドラーに転送します。

ロガーは複数のハンドラーにメッセージを転送できるので、ロガーとハンドラーの関係は多対多であることに注意してください。

このコードを実行したら、:

Code
logger.debug("Attempting to connect to API")

プロジェクトルートの general.log ファイルにそのメッセージが保存されるでしょう。

フォーマッタを設定するLink to this heading

By default, the final log output contains the message part of each LogRecord object. Use a formatter if you want to include additional data. First name and define your formatters - this example defines formatters named verbose and simple:

Python
LOGGING = {
    # ...
    "formatters": {
        "verbose": {
            "format": "{name} {levelname} {asctime} {module} {process:d} {thread:d} {message}",
            "style": "{",
        },
        "simple": {
            "format": "{levelname} {message}",
            "style": "{",
        },
    },
}

style キーワードを使用すると、 str.format() 用の { または string.Template フォーマット用の $ を指定できます。デフォルトは $ です。

含めることができる LogRecord 属性については LogRecord attributes を参照してください。

ハンドラにフォーマッタを適用するには、ハンドラの辞書に formatter エントリを追加します:

Python
"handlers": {
    "file": {
        "class": "logging.FileHandler",
        "filename": "general.log",
        "formatter": "verbose",
    },
}

ロガーの名前空間を使うLink to this heading

無名のロギング設定 "" は任意の Python アプリケーションからログを取り込みます。名前付きロギング設定は、一致する名前のロガーからだけログを取得します。

The namespace of a logger instance is defined using getLogger(). For example in views.py of my_app:

Code
logger = logging.getLogger(__name__)

これは my_app.views 名前空間にロガーを作成します。 __name__ を使うと、プロジェクト内のアプリケーションにおけるログメッセージの出所に基づいて、自動的にそれらを整理できます。また、それによって名前の衝突が起こらなくなります。

my_app.views という名前のロガーマッピングは、このロガーからレコードを取得します:

Python
LOGGING = {
    # ...
    "loggers": {
        "my_app.views": {...},
    },
}

my_app という名前のロガーマッピングはより広く、 my_app 名前空間内のロガー(my_app.viewsmy_app.utils などを含む)からレコードを取得します:

Python
LOGGING = {
    # ...
    "loggers": {
        "my_app": {...},
    },
}

ロガーの名前空間を明示的に定義することもできます:

Code
logger = logging.getLogger("project.payment")

そして、それに応じてロガーマッピングを設定することもできます。

ロガーの階層と伝搬(propagation)を使うLink to this heading

ロガーの命名は 階層的 です。 my_appmy_app.views の親であり、 my_app.viewsmy_app.views.private の親です。特に指定がない限り、ロガーのマッピングは処理したレコードを親に伝播(propagate)します―― my_app.views.private 名前空間のロガーからのレコードは、 my_appmy_app.views の両方のマッピングで処理されます。

この動作を管理するには、定義したマッピングに "propagate" キーを設定します:

Code
LOGGING = {
    # ...
    "loggers": {
        "my_app": {
            # ...
        },
        "my_app.views": {
            # ...
        },
        "my_app.views.private": {
            # ...
            "propagate": False,
        },
    },
}

propagate のデフォルトは True です。この例では、my_app.views.private のログは親プロセスでは処理されませんが、 my_app.views のログは親プロセスで処理されます。

レスポンシブなロギングを設定するLink to this heading

ロギングは、必要な情報ができるだけ多く含まれているときに最も有用であり、目的のために必要な情報だけが含まれているとなお嬉しいです。そして、必要な情報量は、あなたが何をしているかによって異なります。デバッグ中には、本番環境では過剰で役に立たないようなレベルの情報が必要になります。

必要な時に必要な詳細レベルを提供するように、ロギングを設定できます。これを実現するために手動で設定を変更するよりも良い方法は、環境に応じて自動的に設定を適用することです。

例えば、開発環境とステージング環境で環境変数 DJANGO_LOG_LEVEL を適切に設定し、ロガーマッピングで次のように使用できます:

Code
"level": os.getenv("DJANGO_LOG_LEVEL", "WARNING")

- 環境がより低いログレベルを指定しない限り、このコンフィギュレーションは重大度 WARNING 以上のレコードだけをハンドラに転送します。

設定の他のオプション(ハンドラの levelformatter オプションなど)も同様に管理できます。