Edited at

Pythonのlogger(logging)とFlaskのloggerについて


概要

Flaskアプリでログを書きたいときは、app.logger.info("hoge")と書く。(http://flask.pocoo.org/docs/1.0/logging/)

1ファイルに全てのコードを書くときはそれでいいけど(appオブジェクトがそこにあるから)、複数ファイル(モジュール)があるときはどうするの?という疑問を持った。

そういえばPythonのloggingまわりもよく知らないなーということで調べた。


環境


  • Python 3.7

  • Flask 1.0


結論



  • app.loggerは標準ライブラリのlogging.Loggerを取得しているので、同じようにあつかえる

  • appオブジェクトを持たないファイル(モジュール)からは、logging.getlogger('app.flask')を実行することで、app.loggerと同じオブジェクトを取得可能

  • 標準ライブラリのloggingについては、ドキュメントにしっかり載っているので、それを読む


ドキュメント


Flaskのロガーについて


Pythonのlogging


解説(メモ)


app.logger

Flaskのソースコードを読めばわかるが、app.loggerは、logging.getlogger('app.flask')と同じ。

それに加えて、ログレベルの設定やハンドラーの設定、フォーマットの設定が行われている。


logging.getlogger(name)

名前を指定した上で、ロガーオブジェクトを取得する。(正確にはロガーオブジェクトの参照)

場合に応じて、新規作成されるか、生成済みのオブジェクトが返される。

つまり、プログラム内で複数のモジュールからlogging.getlogger('foo')を実行したとき、得られるオブジェクトは同一である。

logging.basicConfig()を始めに実行しておくことで、getlogger()で得られるロガーオブジェクトのデフォルトの設定が可能。(ログのフォーマットや出力先など)


Flaskアプリとロガー

appオブジェクトがあるモジュール(おそらくルーティングが書かれているモジュール)では、app.loggerを使い、それ以外の各モジュールでは、logger = logging.getlogger('flask.app')としてモジュール変数を作成すれば同じようにログは書ける。

各モジュールに"flask.app"とロガー名を書いていくのも微妙な気がするので、そういう場合は、app.loggerを使わずに、どこかでloggerのデフォルトの設定をしておいて、logging.getlogger('__name__')でロガーを取得するのが良いかも。


Pythonのlogging一般の話


  • ログレベルはデフォルトでWARNになっているので、必要に応じてINFODEBUGに変える。

logging.basicConfig(level=logging.INFO)


  • デフォルトでは標準エラー出力に書き込まれるので、ファイルに書き込みたい場合などは、ハンドラーを設定する。


  • logging.info()でもログは書けるが、logging.getlogger(__name__)で取得したロガーに対して、info()などを実行した方が保守性は高そう。ちょっとスクリプト程度ならどちらでも良いけど。


以上です。