🐕

Pythonのロギングを極める!

2024/05/31に公開

ログ出力は、アプリケーションの動作を追跡し、問題の原因を特定するために欠かせない機能です。今回は、Pythonのloggingモジュールを使って、効率的かつ効果的なログ出力を実現する方法をご紹介します。

loggingモジュールの基本

loggingモジュールは、Pythonの標準ライブラリとして提供されているロギング機能を提供するモジュールです。ロガー、ハンドラ、フォーマッタを使って、ログの出力先やフォーマットを柔軟に設定できます。

import logging

# ロガーの作成
logger = logging.getLogger(__name__)

# ログレベルの設定
logger.setLevel(logging.DEBUG)

# ログハンドラの作成
handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)

# ログフォーマットの設定
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)

# ロガーにハンドラを追加
logger.addHandler(handler)

# ログの出力
logger.debug('デバッグメッセージ')
logger.info('情報メッセージ')
logger.warning('警告メッセージ')
logger.error('エラーメッセージ')
logger.critical('致命的なエラーメッセージ')

ログレベルの使い分け

loggingモジュールには、5つのログレベルが用意されています。状況に応じて適切なレベルを選ぶことで、効果的なログ出力ができます。

  • DEBUG: 詳細な情報を出力するためのレベル
  • INFO: 一般的な情報を出力するためのレベル
  • WARNING: 警告を出力するためのレベル
  • ERROR: エラーを出力するためのレベル
  • CRITICAL: 致命的なエラーを出力するためのレベル

ログハンドラの種類

loggingモジュールでは、様々なログハンドラを使ってログの出力先を設定できます。

  • StreamHandler: コンソールにログを出力するハンドラ
  • FileHandler: ファイルにログを出力するハンドラ
  • RotatingFileHandler: 一定のサイズに達したらログファイルをローテーションするハンドラ
  • TimedRotatingFileHandler: 一定の時間間隔でログファイルをローテーションするハンドラ

ログフォーマットのカスタマイズ

フォーマッタを使って、ログの出力形式をカスタマイズできます。

formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)

よく使用されるフォーマット指定子には以下のようなものがあります。

  • %(asctime)s: ログが記録された日時
  • %(name)s: ロガーの名前
  • %(levelname)s: ログレベル
  • %(message)s: ログメッセージ

ログ設定の外部ファイル管理

logging.configモジュールを使って、外部ファイルからログ設定を読み込むことができます。YAMLファイルを使うと、設定を一箇所にまとめて管理できます。

version: 1
formatters:
  simple:
    format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
handlers:
  console:
    class: logging.StreamHandler
    level: DEBUG
    formatter: simple
    stream: ext://sys.stdout
  file:
    class: logging.FileHandler
    level: INFO
    formatter: simple
    filename: application.log
loggers:
  my_module:
    level: ERROR
    handlers: [console]
    propagate: no
root:
  level: DEBUG
  handlers: [console, file]
import logging.config
import yaml

with open('logging.yaml', 'r') as f:
    config = yaml.safe_load(f.read())
    logging.config.dictConfig(config)

logger = logging.getLogger(__name__)

ベストプラクティス

  • ロガーの階層構造を活用して、モジュールごとにログレベルを設定する
  • 環境変数を使って、環境ごとにログ設定を切り替える
  • 例外発生時にlogger.exception()を使って、トレースバックを含む詳細なログを出力する

まとめ

Pythonのloggingモジュールを使うことで、アプリケーションのログ出力をスマートに実現できます。ログレベル、ハンドラ、フォーマットを適切に設定し、外部ファイルからログの設定を読み込むことで、柔軟でメンテナンスしやすいログ出力が可能になります。

参考文献とリソース

Discussion