がじぇったー

お金と家電とプログラミングのブログ

いつもやってるPythonのloggingの設定

こんにちわ

がじぇったー (@hackmylife7) | Twitter


です。


いつも自分がやっているPythonのloggingの設定を共有します。

Print文でログを出力するのはどアンチパターンです。
(個人ツールなら良いかもしれませんが)

qiita.com


Pythonのloggingモジュールを使って、プログラムの処理やエラー出力をログにだすようにしましょう


私がloggingの設定を行う際は

  • 単一のファイルで完結するプログラム
  • 複数ファイルで構成されるプログラム

の二通りで設定しています。

単一のファイルで完結するプログラム


上段でloggingの設定を行っています。

test_logging.py

import sys
import logging
import traceback

logging.basicConfig()
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

message = "this is a test"

def main():
    """
    Main function 
    """
    logger.info({
        'func': sys._getframe().f_code.co_name,
        'action': 'program start',
    })

program
if __name__ == '__main__':
    try:
        main()
    except Exception as e:
        logger.error(e)
        logger.error(traceback.format_exc())
        sys.exit(1)
    finally:
        sys.exit(0)


これを実行すると下記のように出力されます。
logのmessageは辞書型にしておいてよくとツールなどの分析にかけやすいのでおすすめです。

$ ls
test_loggint.py
$ python test_loggint.py 
INFO:test_logging.py:{'func': 'main', 'action': 'program start'}
$ 

複数ファイルで構成されるプログラム

ディレクトリ構成

❯ tree -L 3
.
├── logging.ini
├── modules
│   ├── __init__.py
│   └── utils.py
└── test_logging_2.py

複数ファイルのloggingを設定する際は、logging.iniというファイルを作成し、設定を外だしします。

logging.ini

[loggers]
keys=root,simpleExample

[handlers]
keys=consoleHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler

[logger_simpleExample]
level=INFO
handlers=consoleHandler
qualname=simpleExample
propagate=0

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

[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=

test_logging_2.py

メインプログラムで、modules配下のスクリプトを呼び出します。
import logging.config で前述のloggingの設定を読み込みます。

import logging.config
import sys
import traceback
import modules

# logging
logging.config.fileConfig('logging.ini', disable_existing_loggers=False)
logger = logging.getLogger(__name__)


def main():
    """
    Main function 
    """
    logger.info({
        'func': sys._getframe().f_code.co_name,
        'action': 'program start',
    })
    modules.utils.utils_test()

if __name__ == '__main__':
    try:
        main()
    except Exception as e:
        logger.error(e)
        logger.error(traceback.format_exc())
        sys.exit(1)
    finally:
        sys.exit(0)

modules配下の__init__.py

module配下に作成したutils.pyをimportします

from . import utils

modules配下のutils.py

import logging
import sys
logger = logging.getLogger(__name__)

def utils_test():
    logger.info({
        'func': sys._getframe().f_code.co_name,
        'msg': "test_start"
    })

以上です。

gadgeterkun.hatenablog.com