ロギングの設定と利用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:
import logging
logger = logging.getLogger(__name__)
この宣言はモジュール・レベルで行うのがよいとされています。
そして、ビューなどの関数内で、logger にレコードを送信します。
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 の一つです。したがって、別の例は次のようになります。
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 に以下を追加します:
LOGGING = {
"version": 1, # the dictConfig format version
"disable_existing_loggers": False, # retain the default loggers
}
ほとんどの場合、 disable_existing_loggers を False に設定することで、デフォルトのロギング設定を保持し、拡張できます。
ハンドラを設定するLink to this heading
この例では、Python の FileHandler を使って、レベル DEBUG 以上のログを (プロジェクトルート内の) general.log ファイルに保存する file という名前のハンドラを設定します:
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.
ログレベルはハンドラで設定することもできます(デフォルトでは、ハンドラはすべてのレベルのログメッセージを受け取ります)。上の例を使うと、次のように書けます:
{
"class": "logging.FileHandler",
"filename": "general.log",
"level": "DEBUG",
}
これで、レベル DEBUG 以上のレコードだけを受け付けるようにハンドラを設定できます。
ロガーマッピングを設定するLink to this heading
このハンドラにレコードを送信するには、ロガーマッピングをそのハンドラを使うように設定します。例えば:
LOGGING = {
# ...
"loggers": {
"": {
"level": "DEBUG",
"handlers": ["file"],
},
},
}
マッピングの名前はどのログレコードを処理するかを決定します。この設定 ("") は 無名 です。つまり、 すべての ロガーからのレコードを処理します(レコードを処理するロガーを決定するためにマッピング名を使用する方法については、以下の ロガーの名前空間を使う を参照してください)。
これは DEBUG レベル以上のメッセージを file というハンドラーに転送します。
ロガーは複数のハンドラーにメッセージを転送できるので、ロガーとハンドラーの関係は多対多であることに注意してください。
このコードを実行したら、:
logger.debug("Attempting to connect to API")
プロジェクトルートの general.log ファイルにそのメッセージが保存されるでしょう。
フォーマッタを設定するLink to this heading
デフォルトでは、最終的なログ出力には各 log record のメッセージ部分が含まれます。追加データを含めたい場合はフォーマッタを使います。まずフォーマッタに名前を付けて定義します。この例では verbose と simple という名前のフォーマッタを定義しています:
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 エントリを追加します:
"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:
logger = logging.getLogger(__name__)
これは my_app.views 名前空間にロガーを作成します。 __name__ を使うと、プロジェクト内のアプリケーションにおけるログメッセージの出所に基づいて、自動的にそれらを整理できます。また、それによって名前の衝突が起こらなくなります。
my_app.views という名前のロガーマッピングは、このロガーからレコードを取得します:
LOGGING = {
# ...
"loggers": {
"my_app.views": {...},
},
}
my_app という名前のロガーマッピングはより広く、 my_app 名前空間内のロガー(my_app.views、my_app.utils などを含む)からレコードを取得します:
LOGGING = {
# ...
"loggers": {
"my_app": {...},
},
}
ロガーの名前空間を明示的に定義することもできます:
logger = logging.getLogger("project.payment")
そして、それに応じてロガーマッピングを設定することもできます。
ロガーの階層と伝搬(propagation)を使うLink to this heading
ロガーの命名は 階層的 です。 my_app は my_app.views の親であり、 my_app.views は my_app.views.private の親です。特に指定がない限り、ロガーのマッピングは処理したレコードを親に伝播(propagate)します―― my_app.views.private 名前空間のロガーからのレコードは、 my_app と my_app.views の両方のマッピングで処理されます。
この動作を管理するには、定義したマッピングに "propagate" キーを設定します:
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 を適切に設定し、ロガーマッピングで次のように使用できます:
"level": os.getenv("DJANGO_LOG_LEVEL", "WARNING")
- 環境がより低いログレベルを指定しない限り、このコンフィギュレーションは重大度 WARNING 以上のレコードだけをハンドラに転送します。
設定の他のオプション(ハンドラの level や formatter オプションなど)も同様に管理できます。