Pythonのloggingでログを簡単に出力する方法

Pythonのloggingモジュールは、プログラムの実行中にログメッセージを生成するための柔軟で強力なツールです。このモジュールを使用すると、さまざまなログレベルを設定し、ログメッセージを異なる出力先(コンソール、ファイルなど)に送信できます。

基本的な使い方

モジュールのインポート

import logging

ログレベルの設定

ログレベルを設定することで、記録するメッセージの重要度を制御できます。主なログレベルは以下の通りです。

  • DEBUG: 詳細な情報、主に問題を診断するために使用
  • INFO: 一般的な情報、プログラムの進行状況など
  • WARNING: 警告、注意が必要な状況を示す
  • ERROR: エラー、問題が発生したことを示す
  • CRITICAL: 重大なエラー、プログラムが続行できないことを示す

基本的な設定とログメッセージの出力

# ログの基本設定
logging.basicConfig(level=logging.DEBUG)

# ログメッセージの出力
logging.debug('これはデバッグメッセージです')
logging.info('これは情報メッセージです')
logging.warning('これは警告メッセージです')
logging.error('これはエラーメッセージです')
logging.critical('これは重大エラーメッセージです')

ファイルに出力する基本的なロギングインスタンスの使い方

import logging

logging.basicConfig(filename='app.log', level=logging.DEBUG)

logging.info('logging...')

ログ設定ファイルを使った設定

ルートロガーの設定ファイルを作成します。

logger_settings.py
"""ロギング設定"""
LOG_LEVEL = 'INFO'
LOG_FILE_PATH = 'log/app.log'

# ロギング設定のJSON
LOGGING_CONFIG = {
    "version": 1,
    "formatters": {
        "log_format": {
            "format": "%(asctime)s.%(msecs)-03d,%(levelname)s,%(filename)s,%(funcName)s,%(lineno)s,%(message)s",
            "datefmt": "%y/%m/%d,%H:%M:%S"
        }
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "formatter": "log_format",
            "level": LOG_LEVEL,
            "stream": "ext://sys.stdout"
        },
        "file": {
            "class": "logging.handlers.RotatingFileHandler",
            "formatter": "log_format",
            "level": LOG_LEVEL,
            "filename": LOG_FILE_PATH,
            "maxBytes": 5242880,
            "backupCount": 10,
            "encoding": "utf-8"
        },
        "access": {
            "formatter": "log_format",
            "class": "logging.StreamHandler",
            "stream": "ext://sys.stdout",
        },
    },
    "loggers": {
        "": {
            "handlers": ["console", "file"],
            "level": LOG_LEVEL
        },
        "core.app_manager": {
            "handlers": ["console", "file"],
            "level": LOG_LEVEL,
            "propagate": False
        },
        "services.api_client.http_api_client": {
            "handlers": ["console", "file"],
            "level": LOG_LEVEL,
            "propagate": False
        },
        "uvicorn.error": {
            "level": "INFO"
        },
        "uvicorn.access": {
            "handlers": ["access"],
            "level": "INFO",
            "propagate": False
        },
    }
}

使い方

# logging 準備
import logging.config
from logger_settings import LOGGING_CONFIG
logging.config.dictConfig(LOGGING_CONFIG) # ログ設定ファイルの読込み

logging.info("logging...")

# エラーログなど
try:
  :
except Exception as e:
  logging.error(f"{e}")

loggingモジュールのメソッド(例えば、logging.debug()logging.info()logging.warning()logging.error()logging.critical()など)を使用すると、デフォルトではルートロガー(または共通ロガー)にログを出力します。

複数のロギングインスタンスを使用する

logging.config.dictConfig()を使用して複数のロギングインスタンスで出力を変更することができます。辞書形式でロギング設定を定義する際に、それぞれのロガーに対して異なるハンドラや設定を指定することが可能です。

以下は、複数のロギングインスタンスを設定し、それぞれに異なる出力先を指定する例です。

import logging
import logging.config

# ロギング設定を辞書形式で定義
logging_config = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'simple': {
            'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
        },
    },
    'handlers': {
        'console_handler': {
            'class': 'logging.StreamHandler',
            'formatter': 'simple',
            'level': 'DEBUG',
        },
        'file_handler_a': {
            'class': 'logging.FileHandler',
            'filename': 'logger_a.log',
            'formatter': 'simple',
            'level': 'INFO',
        },
        'file_handler_b': {
            'class': 'logging.FileHandler',
            'filename': 'logger_b.log',
            'formatter': 'simple',
            'level': 'WARNING',
        },
    },
    'loggers': {
        'logger_a': {
            'handlers': ['console_handler', 'file_handler_a'],
            'level': 'DEBUG',
            'propagate': False,
        },
        'logger_b': {
            'handlers': ['console_handler', 'file_handler_b'],
            'level': 'WARNING',
            'propagate': False,
        },
    },
}

# dictConfigを使ってロギング設定を適用
logging.config.dictConfig(logging_config)

# ロガーを取得
logger_a = logging.getLogger('logger_a')
logger_b = logging.getLogger('logger_b')

# ログ出力
logger_a.debug('This is a debug message from logger_a')  # コンソールとlogger_a.logに出力
logger_a.info('This is an info message from logger_a')    # コンソールとlogger_a.logに出力
logger_b.warning('This is a warning message from logger_b')  # コンソールとlogger_b.logに出力
logger_b.error('This is an error message from logger_b')     # コンソールとlogger_b.logに出力

設定の内容について

  • formatters: ログ出力の形式を定義する
  • handlers: console_handler はコンソールに出力し、file_handler_afile_handler_b はそれぞれ異なるファイルに出力する
  • loggers: logger_a はデバッグ以上のメッセージをコンソールと logger_a.log に出力し、logger_b は警告以上のメッセージをコンソールと logger_b.log に出力する

この設定により、各ロギングインスタンスはそれぞれ異なる出力先を持つことができます。これを利用して、アプリケーション内の異なるモジュールやコンポーネントごとにログを管理することができます。

にほんブログ村 IT技術ブログへ

コメント

メールアドレスが公開されることはありません。 が付いている欄は必須項目です