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_a
とfile_handler_b
はそれぞれ異なるファイルに出力するloggers
:logger_a
はデバッグ以上のメッセージをコンソールとlogger_a.log
に出力し、logger_b
は警告以上のメッセージをコンソールとlogger_b.log
に出力する
この設定により、各ロギングインスタンスはそれぞれ異なる出力先を持つことができます。これを利用して、アプリケーション内の異なるモジュールやコンポーネントごとにログを管理することができます。