11
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Python]loggingモジュールざっくり理解

Posted at

登場人物

image.png

Loggerクラス : loggingの主体のはこいつ。ログの生成から目的の場所まで送るまでを管理する。Loggerクラスから生成されるオブジェクト毎にHandlerやFilterを設定できる。Loggerは階層構造(後述)をとり、継承により親の設定を引き継ぐ。

root (rootLoggerオブジェクト) : デフォルトのLoggerクラスのオブジェクトであり全てのロガーの親。必ず1つ。logging.info()等で書かれるログは全てここに流れる。

独自のLoggerオブジェクト : getLogger("ロガー名")により生成する独自のLoggerクラスのオブジェクト。ファイル毎に作成することでどのファイルのログかが明示的にわかり、それぞれにログレベルの設定やハンドラを設定できる。階層構造を作ることが可能(後述)。

LogRecord : ログ本文。Loggerにより生成される。

Handler : LogRecordをどこに届けるか(標準出力やファイル書込み、HTTPリクエストなど)を管理する。Loggerに指定する。
→ 種々のハンドラ:https://docs.python.org/ja/3/howto/logging.html#useful-handlers

Formatter : ログのフォーマットを指定。Handlerに指定する。

Filter : どのログを出力するかの管理。LoggerもしくはHandlerに指定。

Loggerの階層構造

image.png

Loggingのフロー

上の階層構造のmod2mod2.fugaを用いてロギングのフローを確認する。
https://docs.python.org/ja/3/howto/logging.html#logging-flow

loggingtest.py
import logging
import loggingtest2

logger = logging.getLogger("mod2")
logger.setLevel(logging.DEBUG)

# フォーマット生成
formatter = logging.Formatter('parent: %(name)s [%(levelname)s] %(message)s')

# 標準エラー出力のハンドラ生成
handler = logging.StreamHandler()

# ハンドラへの各種設定
handler.setLevel(logging.ERROR)
handler.setFormatter(formatter)

# ロガーにハンドラをアタッチ
logger.addHandler(handler)

if __name__ == "__main__":
    loggingtest2.test()
loggingtest2.py
import logging

def test():
    logger = logging.getLogger("mod2.fuga")
    logger.setLevel(logging.DEBUG)

    # フォーマット生成
    formatter = logging.Formatter('child: %(name)s [%(levelname)s] %(message)s')

    # ハンドラ生成・設定
    handler = logging.StreamHandler()
    handler.setLevel(logging.WARNING)
    handler.setFormatter(formatter)

    logger.addHandler(handler)
    #logger.propagate = False  #後述

    logger.error("bbb")

この状態で実行すると、親のハンドラからも子のハンドラからも出力される。

$ python loggingtest.py
child: mod2.fuga [ERROR] bbb
parent: mod2.fuga [ERROR] bbb

image.png

他も試すとわかるが、loggingtest2.pyのハンドラの条件を"CRITICAL"以上に設定すればchild:~~は出力されなくなり、getLogger()のドットを外し、階層構造をフラットにすると親だったmod2のハンドラは呼ばれなくなるためchild:~~だけが出力される。

propagate属性

propagateの直訳は「伝播する」であり、この属性はLogRecordを親へ伝播させるかを指定する。
上のコードでlogger.propagate = Falseをアンコメントすることで親が呼ばれないことが確認できる。

ロギングの設定の外だし

loggingに対する設定はlogging.confという別ファイルに記述し、fileConfig()で読み出すことが可能。これによりロギングの設定部分を処理本体から切り離すことができる。詳細は公式ドキュメント参照。

11
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?