PythonでLogging(複数Pythonファイル対応)
「素人コードにこれをパパッと加えればたちまちお店の味に」というソフトウェア業界の「味の素」がloggingです。
以前、Javaで同じような記事を書きましたが、Pythonでもログ出力をprintからloggingにするだけで雰囲気がぐっと良くなります。
また積極的にログを残すことができるようになりコードの保守性も向上します。(本来、こっちが主目的)
でもコードを書き進めていくとPythonファイルの数が増えてきますよね。 ファイルが増えるたびにlogger設定を書くのは面倒くさい。
そこで今回はメインとなるPythonファイルでlogger設定を行い、他のPythonファイルでは同じloggerを使い回す方法をご紹介します。 これでPythonファイルがどれだけ増えても安心です。
方法1
必要なコード量が少ないです。
自分のコードだけでなく、利用しているライブラリのログも出力されます。 これが好ましいときもあれば嫌なときもあるでしょう。
嫌な場合は2番目の方法を試してください。
メインとなるPythonファイルに記述
from logging import basicConfig, StreamHandler, DEBUG
basicConfig(
level=DEBUG,
format='%(asctime)s %(name)s:%(lineno)s %(funcName)s [%(levelname)s]: %(message)s'
)
ログ出力したい各ファイルに記述
from logging import getLogger
logger = getLogger(__name__)
logger.debug('hello')
方法2
1番目に比べると少し長いですが大した差はありません。
個人的にはこちらの方がよく使います。
メインとなるPythonファイルに記述
from logging import getLogger, StreamHandler, DEBUG, Formatter
logger = getLogger("<パッケージ名>")
handler = StreamHandler()
handler.setLevel(DEBUG)
handler.setFormatter(Formatter('%(asctime)s %(name)s %(filename)s:%(lineno)s %(funcName)s [%(levelname)s]: %(message)s'))
logger.setLevel(DEBUG)
logger.addHandler(handler)
logger.propagate = False
getLoggerの引数はなんでもよいですが、私はパッケージ名にしてます。
logger.setLevelではロガーがハンドラーに送るログレベルを指定します。 handler.setLevelではハンドラが出力先(画面やファイル等)に送るログレベルを指定します。
ログ出力したい各ファイルに記述
from logging import getLogger
logger = getLogger("<パッケージ名>")
logger.debug('hello')
getLoggerの引数にはメインファイルのgetLoggerで指定したパッケージ名を記載してください。
なお、ファイルごとに振る舞いを変えたい場合(「このモジュールだけログレベルを上げたい」等)は以下の要領で子Loggerを取得して適当に設定変更してください。
logger = getLogger("<パッケージ名>").getChild(__name__)
logger.setLevel(INFO)
<その他loggerの設定>
Formatter
方法1、方法2ともにFormatは以下を参考に適当に変更しましょう。