複数にソースファイルがあったときのロギングを簡単にかっこよくする方法ないかなと探していました。コツはlogging.basicConfigのformatにありました。
「Python ログ」で検索すると、この記事が上位に出てくるのですが、loggingに親でも殺されたかのような書き回しで正直わかりづらい。逆に以下の記事が参考になりました。
logging入門
https://qiita.com/knknkn1162/items/87b1153c212b27bd52b4
pythonのloggingモジュールでログ出力をする時に付加的な情報を出力する方法
https://qiita.com/podhmo/items/efb65ed90871ba2ac544
ちょっと書くぐらいだったら数行でそれなりにかっこよく見えるものが欲しいですよね。ユーザー側(メイン側)のlogging.basicConfigでformatを設定させることです。以下のような階層でファイルがあったとしましょう(本当はフォルダをパッケージ化すべきかもしれませんがあえてしません)。
- main.py #スタートアップファイル
- mylib.py #モジュールその1
+ hoge #フォルダ
- mylib2.py #モジュールその2
各モジュールについて
import logging
logger = logging.getLogger(__name__)
def do():
logger.error("mylib do")
import logging
logger = logging.getLogger(__name__)
def do():
logger.warn("mylib2 do")
##デフォルトの場合
特になにも設定しないでメインプログラムを実行。
import logging
import mylib
import hoge.mylib2
def main():
logging.info("started")
mylib.do()
hoge.mylib2.do()
logging.info("end")
if __name__ == "__main__":
logging.basicConfig(filename = "hoge.log", level = logging.INFO)
main()
結果:
INFO:root:started
ERROR:mylib:mylib do
WARNING:hoge.mylib2:mylib2 do
INFO:root:end
悪くはないけど少しもやもやする。時間の情報はほしい。
##改良版
main.pyのオプションに少し書き足しただけです。
参考:http://docs.python.jp/3/library/logging.html#logrecord-attributes
import logging
import mylib
import hoge.mylib2
def main():
logging.info("started")
mylib.do()
hoge.mylib2.do()
logging.info("end")
if __name__ == "__main__":
logging.basicConfig(filename = "hoge.log", level = logging.INFO,
format='[%(asctime)s] %(module)s.%(funcName)s %(levelname)s -> %(message)s')
main()
結果
[2018-03-07 11:11:49,269] main.main INFO -> started
[2018-03-07 11:11:49,269] mylib.do ERROR -> mylib do
[2018-03-07 11:11:49,270] mylib2.do WARNING -> mylib2 do
[2018-03-07 11:11:49,270] main.main INFO -> end
1行付け足しただけで結構かっこよくなりました。モジュール名や関数名をつけると、デバッグがやりやすくなると思います。好みでformatの引数を追加すればいいだけです。
公式ドキュメントにも書いてありますが、logging.getLoggerは最低限つけるべきです。階層構造が重要なので。
ロガーに名前をつけるときの良い習慣は、ロギングを使う各モジュールに、以下のように名付けられた、モジュールレベルロガーを使うことです:
logger = logging.getLogger(__name__)
これにより、ロガー名はパッケージ/モジュール階層をなぞり、ロガー名だけで、どこでイベントのログが取られたか、直感的に明らかになります。