ロギング。ちょっとしたプログラムの場合、ついついprintで代用しがちだ。しかし今回はloggingを使ってみよう。
開発環境:
Python 3.9.2
参考情報:
まずはロガーを初期化するためにYAMLを用意しよう。
好みに合わせてログのフォーマットを「formatters」にて定義する。
formatters:
brief:
format: '%(asctime)s -%(levelname)s- %(module)s : %(message)s'
precise:
format: '%(asctime)s -%(levelname)s- %(threadName)s [LineNo.: %(lineno)s] %(module)s : %(message)s'
ログファイルへの出力、コンソールへの出力は「handlers」にて定義する。ロガー毎にハンドラをカスタマイズしたい場合は、定義を追加する。
ファイルへ出力する際はファイルサイズの上限と世代数を定めておこう。
handlers:
file:
class: logging.handlers.RotatingFileHandler
level: DEBUG
filename: logs/logger.log
maxBytes: 10485760
backupCount: 5
formatter: precise
console:
class: logging.StreamHandler
level: DEBUG
formatter: brief
最後にロガーだ。ルートロガーのみにハンドラを定義するか、個別のロガーにもハンドラを定義するかを定める。下記は個別のロガーにハンドラを定義し、propagateをfalseにしている。propagateをtrueにすると個別のロガーのハンドラから上位のロガーのハンドラ(この投稿ではルートロガーのハンドラ)へログ出力が伝播する。伝播すると、ログ出力が重複してしまう。言い換えると同じ内容の行が複数出力される。このためpropagateをfalseにする。
loggers:
foo:
level: DEBUG
handlers: [file, console]
propagate: false
myapp:
level: DEBUG
handlers: [file, console]
propagate: false
root:
level: WARNING
handlers: [file, console]
propagate: falseの場合のコンソールへのログ出力:
2021-05-03 00:17:15,453 -INFO- foo : logdir=./logs YAML=./logging.yaml
2021-05-03 00:17:15,454 -DEBUG- myapp : MyApp debug
2021-05-03 00:17:15,455 -INFO- myapp : MyApp info
2021-05-03 00:17:15,455 -INFO- foo : completed!
propagate: trueの場合のコンソールへのログ出力:
2021-05-03 00:24:32,418 -INFO- foo : logdir=./logs YAML=./logging.yaml
2021-05-03 00:24:32,418 -INFO- foo : logdir=./logs YAML=./logging.yaml
2021-05-03 00:24:32,418 -DEBUG- myapp : MyApp debug
2021-05-03 00:24:32,418 -DEBUG- myapp : MyApp debug
2021-05-03 00:24:32,419 -INFO- myapp : MyApp info
2021-05-03 00:24:32,419 -INFO- myapp : MyApp info
2021-05-03 00:24:32,420 -INFO- foo : completed!
2021-05-03 00:24:32,420 -INFO- foo : completed!
関連ファイル:
※拡張子は適切な状態にしよう。
まとめ:
loggingのコンフィグレーションとしてYAMLを使用可能
ログ出力が重複する際はpropagateをfalseにする
設計思想により、ルートロガーにのみハンドラを定義することも有効な一手に