3
6

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 1 year has passed since last update.

python ロギング dictConfigの使い方 

Last updated at Posted at 2022-01-10

pythonでLOGしたことなかったのでやってみた。
ログの設定内容はsettings/config.pyにまとめて、main.py(root)からimportして使うかたちを取ることにした。

infoは頻繁にログ出力することからログローテーションをつかう。これにより、ログサイズが指定サイズ(maxByte)を超えたら自動的に新しいログファイルが作成されることになる。backupCount回まで作成したら、後ろから上書き(厳密には違うが)されていくので1ファイルがデカくなりすぎることはない。

settings/config.py
import os
"""
参考にした書き方
https://stackoverflow.com/questions/7507825/where-is-a-complete-example-of-logging-config-dictconfig

"""
import os
"""
参考にした書き方
https://stackoverflow.com/questions/7507825/where-is-a-complete-example-of-logging-config-dictconfig

"""
"""
ログ設計指針
https://qiita.com/nanasess/items/350e59b29cceb2f122b3

◆バッチ処理の例◆
INFO 処理開始時
INFO 途中経過
INFO 処理終了時
WARN イベント発生時
ERROR 例外発生時
INFO その他、必要に応じて

◆WEBアプリケーションの例◆
INFO リクエスト開始時 - 処理概要、実行クラス名、メソッド名
INFO 途中経過 - 実行条件、処理対象オブジェクトのキーとなる値等(customer_id, order_id 等)
INFO 処理終了時 - 実行結果(OK/NG 等)、リダイレクト先
WARN イベント発生時 - 画面に表示したエラーメッセージ等
ERROR 例外発生時 - 例外クラス、例外メッセージ
INFO その他、必要に応じて
"""

"""    ★ Python ログレベルについて ★
DEBUG	10	問題探求に必要な詳細な情報を出力したい場合
INFO	20	想定内の処理が行われた場合
WARNING	30	想定外の処理やそれが起こりそうな場合
ERROR	40	重大な問題により、機能を実行出来ない場合
CRITICAL	50	プログラムが実行不可となるような重大なエラーが発生した場合
"""

# PATH
SETTINGS_DIR = __file__  # ここのパス
ROOT_DIR = '/'.join(SETTINGS_DIR.split('/')[:-2])   # rootは1つ上の階層
LOG_DIR = os.path.join(ROOT_DIR, 'logs')
MAIN_LOG_DIR = os.path.join(LOG_DIR, 'main')        # main.py用
NB_LOG_DIR = os.path.join(LOG_DIR, 'notebook')      # jupytenotebook用
# ディレクトリ作成
if not os.path.exists(LOG_DIR):
    os.mkdir(LOG_DIR)
if not os.path.exists(MAIN_LOG_DIR):
    os.mkdir(MAIN_LOG_DIR)
if not os.path.exists(NB_LOG_DIR):
    os.mkdir(NB_LOG_DIR)

LOGGING_CONFIG = {
    'version': 1,
    # loggersで''として指定してもOK
    # 'root': {
    #     'level': 'NOTSET',
    #     'handlers': ['debug_console_handler', 'info_rotating_file_handler', 'error_file_handler'],
    # },
    'loggers': {
        '': {  # root
            'level': 'NOTSET',
            'handlers': ['debug_console_handler', 'info_rotating_file_handler', 'error_file_handler'],
        },
        'notebook': {
            'level': 'NOTSET',
            'handlers': ['info_notebook', 'error_notebook'],
        },
    },
    'handlers': {
        'debug_console_handler': {
            'level': 'DEBUG',
            'formatter': 'info',
            'class': 'logging.StreamHandler',
            'stream': 'ext://sys.stdout',
        },
        # ログ・ファイルのサイズがmaxBytes以上になったらinfo1.2.3..nと
        # 新しいログファイルを作成(rotating)する
        # backupCount回まで作成したら、後ろから上書きされていく(厳密には違うが)
        'info_rotating_file_handler': {
            'level': 'INFO',
            'formatter': 'info',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': os.path.join(MAIN_LOG_DIR, 'info.log'),
            'mode': 'a',
            'maxBytes': 1048576,  # 1MBまで
            'backupCount': 10    # 10ローテ
        },
        'error_file_handler': {
            'level': 'ERROR',
            'formatter': 'error',
            'class': 'logging.FileHandler',
            'filename': os.path.join(MAIN_LOG_DIR, 'error.log'),
            'mode': 'a',
        },
        'info_notebook': {
            'level': 'INFO',
            'formatter': 'info',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': os.path.join(NB_LOG_DIR, 'info.log'),
            'mode': 'a',
            'maxBytes': 1048576,  # 1MBまで
            'backupCount': 10    # 10ローテ
        },
        'error_notebook': {
            'level': 'ERROR',
            'formatter': 'error',
            'class': 'logging.FileHandler',
            'filename': os.path.join(NB_LOG_DIR, 'error.log'),
            'mode': 'a',
        },
    },
    'formatters': {
        'info': {
            'format': '%(asctime)s-%(levelname)s-%(name)s::%(module)s|%(lineno)s:: %(message)s'
        },
        'error': {
            'format': '%(asctime)s-%(levelname)s-%(name)s-%(process)d::%(module)s|%(lineno)s:: %(message)s'
        },
    },

}

https://blog.hiros-dot.net/wp-content/uploads/2021/01/ScreenShot_55.jpg
image.png

main.py
from logging import getLogger,config
from settings.config import LOGGING_CONFIG 

config.dictConfig(LOGGING_CONFIG)
logger = getLogger()

for i in range(1000):
    if i % 2 ==0:
        logger.info(i)
    if i % 3 == 0:
        logger.error(i)
出力
2022-01-10 12:09:55,249-INFO-root::899213607|14:: 0
2022-01-10 12:09:55,250-ERROR-root::899213607|16:: 0
2022-01-10 12:09:55,251-INFO-root::899213607|14:: 2
2022-01-10 12:09:55,252-ERROR-root::899213607|16:: 3
2022-01-10 12:09:55,253-INFO-root::899213607|14:: 4
2022-01-10 12:09:55,253-INFO-root::899213607|14:: 6
2022-01-10 12:09:55,254-ERROR-root::899213607|16:: 6
2022-01-10 12:09:55,256-INFO-root::899213607|14:: 8
2022-01-10 12:09:55,256-ERROR-root::899213607|16:: 9
2022-01-10 12:09:55,257-INFO-root::899213607|14:: 10
2022-01-10 12:09:55,258-INFO-root::899213607|14:: 12
2022-01-10 12:09:55,258-ERROR-root::899213607|16:: 12
2022-01-10 12:09:55,260-INFO-root::899213607|14:: 14
2022-01-10 12:09:55,260-ERROR-root::899213607|16:: 15
2022-01-10 12:09:55,262-INFO-root::899213607|14:: 16
2022-01-10 12:09:55,262-INFO-root::899213607|14:: 18
2022-01-10 12:09:55,263-ERROR-root::899213607|16:: 18
2022-01-10 12:09:55,264-INFO-root::899213607|14:: 20
2022-01-10 12:09:55,265-ERROR-root::899213607|16:: 21
2022-01-10 12:09:55,266-INFO-root::899213607|14:: 22
2022-01-10 12:09:55,267-INFO-root::899213607|14:: 24
2022-01-10 12:09:55,268-ERROR-root::899213607|16:: 24
2022-01-10 12:09:55,269-INFO-root::899213607|14:: 26
2022-01-10 12:09:55,270-ERROR-root::899213607|16:: 27
2022-01-10 12:09:55,271-INFO-root::899213607|14:: 28
2022-01-10 12:09:55,272-INFO-root::899213607|14:: 30
2022-01-10 12:09:55,272-ERROR-root::899213607|16:: 30
2022-01-10 12:09:55,274-INFO-root::899213607|14:: 32
2022-01-10 12:09:55,275-ERROR-root::899213607|16:: 33
2022-01-10 12:09:55,275-INFO-root::899213607|14:: 34
2022-01-10 12:09:55,277-INFO-root::899213607|14:: 36
2022-01-10 12:09:55,278-ERROR-root::899213607|16:: 36
2022-01-10 12:09:55,279-INFO-root::899213607|14:: 38
2022-01-10 12:09:55,280-ERROR-root::899213607|16:: 39
2022-01-10 12:09:55,281-INFO-root::899213607|14:: 40
2022-01-10 12:09:55,281-INFO-root::899213607|14:: 42
2022-01-10 12:09:55,282-ERROR-root::899213607|16:: 42
2022-01-10 12:09:55,284-INFO-root::899213607|14:: 44
2022-01-10 12:09:55,285-ERROR-root::899213607|16:: 45
2022-01-10 12:09:55,286-INFO-root::899213607|14:: 46
2022-01-10 12:09:55,287-INFO-root::899213607|14:: 48
2022-01-10 12:09:55,288-ERROR-root::899213607|16:: 48
2022-01-10 12:09:55,288-INFO-root::899213607|14:: 50
2022-01-10 12:09:56,121-INFO-root::899213607|14:: 994
2022-01-10 12:09:56,122-INFO-root::899213607|14:: 996
2022-01-10 12:09:56,124-ERROR-root::899213607|16:: 996
2022-01-10 12:09:56,125-INFO-root::899213607|14:: 998
2022-01-10 12:09:56,126-ERROR-root::899213607|16:: 999
3
6
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
3
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?