Pythonのloggingモジュールの詳細な使い方

loggingモジュールは、アプリケーションの動作状況を記録し、デバッグや問題解析に役立てるための標準ライブラリです。主な利用方法には以下の2つがあります:

  • logging.basicConfig()
  • logging.getLogger()

基本的なログ出力

import logging

logging.debug("デバッグメッセージ")
logging.info("情報メッセージ")
logging.warning("警告メッセージ")
logging.error("エラーメッセージ")
logging.critical("重大エラーメッセージ")

このコードを実行すると、次のように出力されます:

WARNING:root:警告メッセージ
ERROR:root:エラーメッセージ
CRITICAL:root:重大エラーメッセージ

これは、デフォルトのログレベルがWARNINGであるため、それ以上の重要度を持つメッセージのみが出力されるからです。

basicConfigによるカスタマイズ

import logging

logging.basicConfig(
    level=logging.DEBUG,
    format="%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s",
    datefmt='%Y/%m/%d %H:%M:%S',
    filename='app.log',
    filemode='a'
)

logging.debug("デバッグメッセージ")
logging.info("情報メッセージ")
logging.warning("警告メッセージ")
logging.error("エラーメッセージ")
logging.critical("重大エラーメッセージ")

この設定により、すべてのレベルのログがファイルapp.logに追記され、以下のような形式で記録されます:

2018/07/07 16:44:54 example.py[line:9] DEBUG デバッグメッセージ
2018/07/07 16:44:54 example.py[line:10] INFO 情報メッセージ
2018/07/07 16:44:54 example.py[line:11] WARNING 警告メッセージ
2018/07/07 16:44:54 example.py[line:12] ERROR エラーメッセージ
2018/07/07 16:44:54 example.py[line:13] CRITICAL 重大エラーメッセージ

getLoggerによる高度な制御

import logging

# Loggerインスタンスを取得(名前なしでroot)
logger = logging.getLogger()

# ファイルハンドラとストリームハンドラを作成
file_handler = logging.FileHandler('detailed.log', encoding='utf-8')
console_handler = logging.StreamHandler()

# フォーマッタを定義
formatter = logging.Formatter("%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s")

# ログレベルを設定
logger.setLevel(logging.DEBUG)
console_handler.setLevel(logging.INFO)
file_handler.setLevel(logging.WARNING)

# フォーマッタをハンドラに適用
file_handler.setFormatter(formatter)
console_handler.setFormatter(formatter)

# ハンドラをLoggerに追加
logger.addHandler(file_handler)
logger.addHandler(console_handler)

# ログ出力
logging.debug("デバッグメッセージ")
logging.info("情報メッセージ")
logging.warning("警告メッセージ")
logging.error("エラーメッセージ")
logging.critical("重大エラーメッセージ")

この場合、コンソールにはINFO以上が表示され、ファイルにはWARNING以上のログのみが記録されます。

主要コンポーネントの概要

  • Logger:ログのエントリポイント。階層構造を持ち、名前で識別される。
  • Handler:ログの出力先(ファイル、コンソールなど)を管理。
  • Formatter:ログの出力形式を定義。
  • Filter:特定の条件を満たすログのみを通過させるフィルタリング機能。

設定ファイルによる構成

logging.confという名前の設定ファイルを使用することも可能です:

[loggers]
keys=root,appLogger

[handlers]
keys=fileHandler,consoleHandler

[formatters]
keys=detailedFormatter

[logger_root]
level=WARNING
handlers=consoleHandler

[logger_appLogger]
level=DEBUG
handlers=fileHandler,consoleHandler
qualname=appLogger
propagate=0

[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=detailedFormatter
args=('app.log', 'a')

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

[formatter_detailedFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=%Y-%m-%d %H:%M:%S

この設定を読み込むコード:

import logging.config

logging.config.fileConfig('logging.conf')
logger = logging.getLogger('appLogger')

logger.debug("デバッグ情報")
logger.info("通常情報")
logger.warning("注意")

複数モジュールでの利用

メインモジュールで一度設定すれば、他のモジュールでも同じロガー名でアクセスできます:

# main.py
import logging.config
logging.config.fileConfig('logging.conf')
logger = logging.getLogger('main')
logger.info("メインモジュール開始")

import submodule
submodule.do_something()
# submodule.py
import logging
logger = logging.getLogger('main.submodule')

def do_something():
    logger.info("サブモジュール処理中")

このようにすることで、一貫したログ出力が可能になります。

タグ: Python logging debugging

7月9日 21:46 投稿