概要
Pythonのloggingでログ出力する際、出力したログ内容を変数に格納したい。一度ファイルに書き出してから読み込んでもよいが、直接変数に格納するに越したことはないだろう。
実装例
logging.configなし
もっとも単純な実装方法は、組み込みのStreamHandlerをインスタンス化するときにStringIOを渡すこと。
sample.py
import io
import logging
# 文字列バッファ
str_io = io.StringIO()
# ロガー
logger = logging.getLogger('sample')
logger.setLevel(logging.INFO)
# 組み込みのStreamHandlerにStringIOを渡す
handler = logging.StreamHandler(str_io)
handler.setFormatter(logging.Formatter('%(asctime)s %(name)s %(levelname)s %(message)s'))
# ログ出力(この時点ではバッファに書き込まれるだけ)
logger.info('info')
# ログ内容を変数に格納
log_text = str_io.getvalue()
# 表示
print('log : ' + log_text)
上記の例でlogging.config.dictConfigを使う場合は、StreamHandlerのstreamに"est://__main__.str_io"を設定する。ただ、さすがに変数名を設定ファイルに直接記載するのは憚られるので、StringIOを出力対象とする独自Handlerを定義した方がよいだろう。
logging.configあり
StreamHandlerを継承した独自Handlerを定義する。StringIOインスタンスの配置場所や参照方法はお好みで。
my_util.py
import io
from logging import StreamHandler
class StringHandler(StreamHandler):
"""ログ出力を変数に格納する独自Handler"""
str_io = io.StringIO()
def __init__(self):
StreamHandler.__init__(self, StringHandler.str_io)
sample2.py
import io
from logging import getLogger, config
from my_util import StringHandler
# ログ設定
config.dictConfig({
'version': 1,
'formatters': {
'simple': {
'format': '%(asctime)s %(name)s %(levelname)s %(message)s'
}
},
'handlers': {
'string': {
'class': 'my_util.StringHandler',
'formatter': 'simple'
}
},
'loggers': {
'sample': {
'level': 'INFO',
'handlers': ['string']
}
}
})
# ロガー
logger = getLogger('sample')
# ログ出力(この時点ではバッファに書き込まれるだけ)
logger.info('info')
# ログ内容を変数に格納
log_text = StringHandler.str_io.getvalue()
# 表示
print('log : ' + log_text)