logging.config.fileConfig()についてまとめる
概要
log出せ、指定の形式でだせ、ファイルに保存しろ、コンソールにも出力しろ。
そんな時に出会ったloggingモジュール、今まで設定をちまちま毎回書いていてめんどくさいなと感じていた。 たがファイルに設定を記述しておくだけで読み込んでloggerを初期化してくれる便利な機能があるらしい!そんなfileConfigについて調べたところどうも覚えることは難しそう。
だからまとめる。
Logger の構造
PythonのLoggerの構造は以下のようになっている
root
├───────────────────┐
user1 user2
├─────────┐ ├─────────┐
user1_1 user1_2 user2_1 user_2_2
rootのみがデフォルトで作成されており、logging.info()
やlogging.error()
などのlogging
直下のコマンドを使用すると参照される。
また、logging.getLogger()
で引数なしまたはroot
を引数にするとrootLoggerが返却される
rootLogger以外はすべてユーザが定義する必要がある。
e.g.)
- user1:
logging.getLogger("user1")
- user1_1:
logging.getLogger("user1.user1_1")
orlogging.getLogger("user1").getChild("user1_1")
ちなみにLogger間のLogメッセージの遷移は以下のようになっている。 それぞれのLoggerの設定に従い処理をした後に上位のLoggerにLogメッセージを伝搬する。
log_message > user1_1 > user1 > root ↓output ↓output ↓output
Logger の設定
Loggerを設定するにはHandlerやFormatter、Filterなどを定義し、Loggerオブジェクトに投入する必要がある。
しかし、その設定は長くなりプログラムファイル上部を大きく占めてしまう。
これらの設定を別ファイルに保存し、プログラムファイル自体を簡潔にするのがlogging.config.fileConfig()
である。
fileConfig()
使用方法
1ファイル単体でのみLoggerを使用する場合
main.py
from logging import getLogger, config config.fileConfig('./config/logging.conf') logger = getLogger(__name__) logger.info("this is a information message.")
複数ファイルで設定を共有する場合(特別異なることはないがimportの順番で詰まった)
main.py
from logging import getLogger, config config.fileConfig('./config/logging.conf') logger = getLogger(__name__) import child logger.info("this message from main.py")
child.py
from logging import getLogger logger = getLogger(__name__) logger.info("this message from child.py")
fileConfig()
設定ファイル書式
例
以下の例では、これらの設定をしている
- rootLogger
- logFileHandler: Debug以上をファイルに書き出し
- consoleHandler: Info以上を標準出力に書き出し
[loggers] keys=root [handlers] keys=logFileHandler,consoleHandler [formatters] keys=logFileFormatter,consoleFormatter [logger_root] level=DEBUG handlers=logFileHandler,consoleHandler [handler_logFileHandler] class=FileHandler level=DEBUG formatter=logFileFormatter args=("./log/app.log", "w", "utf-8") [handler_consoleHandler] class=StreamHandler level=INFO formatter=consoleFormatter args=(sys.stdout,) [formatter_logFileFormatter] format=%(asctime)s|%(levelname)-8s|%(name)s|%(funcName)s|%(message)s [formatter_consoleFormatter] format=[%(levelname)-8s]%(funcName)s - %(message)s
[loggers]
- keys: 作成するLoggerインスタンス名を記述
[handlers]
- keys: 作成するHandlerインスタンス名を記述
[formatters]
- keys: 作成するFormatterインスタンス名を記述
[loger_<logger_name>]
- level: メッセージを出力する最低レベルを指定する。Handlerに渡す前に処理されるので注意。
- handlers: 適用するHandlerインスタンス名を指定する
[hander_<handler_name>]
- class:実装するHandlerクラスを指定する
- StreamHandler: メッセージを指定されたストリームに出力する。
- FileHandler: メッセージを指定されたファイルに出力する。
- level: 指定されたレベル以上のメッセージのみが出力される。
- formatter: 出力時のメッセージ成型に使用するFormatter名を指定する。
args: Handlerクラスをインスタンス化する際に使用する引数。Handlerクラスの公式ドキュメントを参照すること。
※tuple形式で渡すので引数のキーワード指定は使用不可、位置指定で渡す。
※tuple形式で渡すので引数が1つの場合は
,
を忘れないこと
[formatter_<formatter_name>]
- format: 使いそうなもののみ抜粋。詳細はこちらまで
書式 | 説明 |
---|---|
%(asctime)s | ログ生成日時 "yyyy-mm-dd HH:MM:SS,sss" |
%(filename)s | 呼び出し元ファイル名 |
%(funcName)s | 呼び出し元関数名 |
%(levelname)s | ログレベル ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL') |
%(lineno)d | 呼び出し元ファイル内の行番号 |
%(message)s | 呼び出し時に引数で指定した値logger.info("ここ") |
%(module)s | 呼び出し元モジュール名 |
%(name)s | 使用されたlogger名 |
注意事項
fileConfig()
ではFilterの項目は設定できない。
使用したい場合はdictConfig()
を使用しろと公式にあったので合わせて参照してほしい。