TIL

Today I Learned. 知ったこと、学んだことを書いていく

importしたモジュール内でもログを出力する - logging

loggingを使用してimportしたモジュール内でもログを出力する方法

コードにログの設定を記述してもよいが、設定ファイルを使用することで管理がしやすくなる。また、開発時と稼働時でログレベルのみ変更すればよいことからいいとされている(?)

設定ファイルの基本的な記述の仕方については省略する(参考文献を参考に記述)

まずは一つのモジュールのみでログを出力してみる

一つのモジュールのみでログを出力

importはせずに一つのモジュール内でのみログを出力するとする。その時には何も気にせずに設定を行えばよい。

まず、設定ファイルから

logger.conf

[loggers]
keys=root

[handlers]
keys=consoleHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)

[formatter_simpleFormatter]
format=%(asctime)s:%(levelname)s (%(filename)s:%(lineno)s) %(message)s
; 時間の表示形式を設定
datefmt=%Y-%m-%d %H:%M:%S


コンソールにログを出力するための設定を行っている

次に、ログを出力するプログラム

main.py

#! /usr/bin/env python
# -*- coding: utf-8 -*-

from logging import getLogger, config
config.fileConfig("logger.conf")
_logger = getLogger(__name__)

if __name__ == "__main__":
    _logger.debug("hello!")


DEBUG出力で"hello!"と出力している


main.pyを実行してみる

実行結果

$ python main.py
2017-08-22 21:22:49:DEBUG (main.py:12) hello!

しっかりとログが出力されている


次にimportしたモジュール内でログを出力してみる

importしたモジュール内でログを出力

以下のようなsample.pyを作成する
#! /usr/bin/env python
# -*- coding: utf-8 -*-

from logging import getLogger
_logger = getLogger(__name__)

def sum(a, b):
    _logger.info(f"{a} + {b} = {a+b}")

サブモジュールとして考えているため、設定ファイルの読み込みは行っていない


sample.pyからログを出力できるようにlogger.confを変更
[loggers]
keys=root, sample

[handlers]
keys=consoleHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler

[logger_sample]
level=DEBUG
handlers=consoleHandler
qualname=sample
propagate=0

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)

[formatter_simpleFormatter]
format=%(asctime)s:%(levelname)s (%(filename)s:%(lineno)s) %(message)s
; 時間の表示形式を設定
datefmt=%Y-%m-%d %H:%M:%S


  • loggersセクションにsampleを追加
  • logger_sampleセクションを追加
    • qualnameの値にはsample
    • propagateの値には0

logger_xxxqualnameにはこのロガーを使用するモジュール名を指定するのかな?
また、logger_xxxpopagate0を設定することで下位ロガーにログを出力したときに上位ロガーには出力されないようにできる


main.pyからsample.sum()を呼ぶように変更
#! /usr/bin/env python
# -*- coding: utf-8 -*-

import sample

from logging import getLogger, config
config.fileConfig("logger.conf")
_logger = getLogger(__name__)

if __name__ == "__main__":
    _logger.debug("hello!")
    sample.sum(1, 2)


実行してみる

実行結果

$ python main.py
2017-08-22 22:13:05:DEBUG (main.py:13) hello!
2017-08-22 22:13:05:INFO (sample.py:11) 1 + 2 = 3

参考文献

logging.config使ったpythonのロギングについてメモ | takemikami’s note

Python logging 設定ファイルによるログ出力の設定 - Symfoware