logging
Pythonのloggingについて、以下のログ設定を例に説明 loggerとfilterとhandler
logger -> filter -> handler の順番でログメッセージが渡される
https://gyazo.com/d710a53a53221628195876ce8dc19ad4
Python公式の図がありました。
次の図はログイベントが logger と handler をどう流れるかを示しています。
https://docs.python.org/ja/3/_images/logging_flow.png
設定(TBD: 上記の絵と設定は別)
code:mylogging.py
import logging
from logging.config import dictConfig
config = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': '%(levelname)s %(asctime)s %(name)s %(message)s', },
'verbose': {
'format': '%(levelname)s %(asctime)s %(name)s %(process)d %(thread)d %(message)s' },
},
'handlers': {
'debug-console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'verbose'
},
'prod-console': {
'level': 'INFO',
'class': 'logging.StreamHandler',
'formatter': 'standard'
},
'sentry': {
'level': 'WARNING',
'class': 'raven.handlers.logging.SentryHandler',
},
},
'root': { # 全てキャッチする
'level': 'NOTSET',
},
'loggers': {
'django': {
'level': 'ERROR', # Djangoモジュール由来のログをERROR以上のみに制限
'propagate': False
}
'django.db.backends': {
'level': 'DEBUG', # DBに発行するSQLログを出力(実際の出力はhandlerの方で制御する)
'propagate': False
},
}
}
dictConfig(config)
ref:
rootとはなにか
config['loggers'][''] の別名
loggersとpropagate
config['loggers'] に設定された全ての ロガー は propagate=True なら受け取ったログメッセージを 上位の ロガー に転送する
上位のロガーとは、ロガー名をドット区切りで末尾要素を削っていったもの
'django.db.backends' -> 'django.db' -> 'django' -> '' (root)
ロガー設定が存在しなければ、 propagate=True として扱われて、さらに上位のロガーに渡される
多くのPythonコードでは logger = logging.getLogger(__name__) としている
config['loggers'] には apps.login.views がないので、 apps.login ロガーにpropagateされる
apps.login も apps もないので、最終的に '' (root) ロガーにpropagateされる
filter
各ロガーはfilterを持っている。
filterはfilteringするのが目的。
TBD
handler
各ロガーはhandlerを持っている。
handlerはログを実際にどこに送るかを決めるのが目的
loglevel
logger, filter, handlerそれぞれ、loglevelを設定でき、設定されたloglevel以上のログしか通さない
今回、debug-console handlerはDEBUGレベルで通したい。
rootロガーのloglevelにWARNINGを設定してしまうと、WARNING以下のログはhandlerまで渡らない
NOTSET=0
DEBUG=10
INFO=20
WARNING=30
ERROR=40
CRITICAL=50
例:
config['loggers']['django.db.backends'] に level=DEBUG と propagate=False を設定
root にはこない (django.db にも行かないし django にも行かない)
DEBUGのログをhandlerに渡す
ログ出力命令の経路とレベル比較
basicConfigで指定したlevelは、 rootロガー に適用されます。 logging.info() といった呼び出しはこの rootロガー に渡されます。
handlerに指定したlevelは、そのhandlerに適用されます。
levelにはそれぞれ数値が割り当てられています(公式ドキュメントに解説があります)。 infoは20, warningは30, errorは40, という値です
ログ出力の命令は logging.info -> rootロガー -> handler の順に渡されます(実際はfilter等も間にある)
ログ出力 logging.info('...') はlevel=20です。rootロガーに設定したlevel以上であればhandlerに渡され、handlerに設定したlevel以上であれば出力されます。
このため、命令が渡される経路上のどこかが level>20 の場合、ログは出力されません
disable_existing_loggers
LOGGING dictConfig 内の disable_existing_loggers キーが True (デフォルトです) にセットされている場合、デフォルト設定のすべてのロガーが無効化されます。無効化は、削除とは違います; ロガーは存在はしており、記録されたものを黙って破棄します。親ロガーに伝達もしません。'disable_existing_loggers': True は、とても慎重に扱う必要があります; あなたの期待しない動作かもしれません。代わりに disable_existing_loggers を False にセットして、デフォルトロガー設定の必要な部分を再定義できます
関連する話題
タグ