ログの出力2025年8月9日 | |
はじめにPython におけるログの出力について。 環境Python 3.10.17 ログの出力Python におけるログの出力には、標準ライブラリの logging が使える。 log_test.py
import logging
# ログレベルの設定
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# ログの出力
logger.debug("デバッグ情報")
logger.info("一般的な情報")
logger.warning("警告メッセージ")
logger.error("エラーメッセージ")
logger.critical("重大なエラー")
実行 $ python log_test.py INFO:__main__:一般的な情報 WARNING:__main__:警告メッセージ ERROR:__main__:エラーメッセージ CRITICAL:__main__:重大なエラー ファイルへの出力log_test2.py
import logging
import sys
# ロガーの設定
def setup_logger(name, log_file=None, level=logging.INFO):
logger = logging.getLogger(name)
logger.setLevel(level)
# フォーマットの設定
formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
# コンソール出力
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)
# ファイル出力
if log_file:
file_handler = logging.FileHandler(log_file, encoding='utf-8')
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
return logger
logger = setup_logger(__name__, 'app.log')
logger.info("アプリケーションが開始されました")
これは、指定した名前でロガーを作成して、コンソール出力のハンドラと、ファイル出力のハンドラを設定している。 実行 $ python log_test2.py 2025-07-16 14:38:38,056 - __main__ - INFO - アプリケーションが開始されました app.logにも書き込まれる。 ミリ秒の小数点をピリオドにするログの時間のミリ秒の小数点がカンマになっているのが気になるなら、以下のようにしてピリオドに変更できる。
# フォーマットの設定
formatter = logging.Formatter(
'%(asctime)s.%(msecs)03d - %(name)s - %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
実行 $ python log_test2.py 2025-07-16 14:43:37.982 - __main__ - INFO - アプリケーションが開始されました コンフィグファイルセットアップ部分を外部ファイルにすることもできる。 log_test3.py
import logging.config
logging.config.fileConfig('logging.conf')
logger = logging.getLogger('app')
logger.info("アプリケーションが開始されました")
logging.conf
[loggers]
keys=root,app
[handlers]
keys=consoleHandler,fileHandler
[formatters]
keys=simpleFormatter
[logger_root]
level=DEBUG
handlers=consoleHandler
[logger_app]
level=INFO
handlers=consoleHandler,fileHandler
qualname=app
propagate=0
[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)
[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=simpleFormatter
args=('app.log', 'a', 'utf-8')
[formatter_simpleFormatter]
format=%(asctime)s.%(msecs)03d - %(name)s - %(levelname)s - %(message)s
datefmt=%Y-%m-%d %H:%M:%S
上の例では、ロガーが root と app の2つ設定されている。root はルートロガーで、最上位ロガーである。logger_root で root の処理レベルやハンドラを設定している。ここで level=DEBUG というのは、DEBUG 以上のメッセージを出力するという意味である (NOTSET というすべて表示するものもあるが、DEBUG と変わらない)。 logger_app で app の設定をしている。qualname はロガーの名前で、getLogger() で指定するものである。propagate は上位ロガーに伝播させるかどうかのスイッチで、0 なら伝播させない。1 にすると root の方でも処理される。それぞれのハンドラで処理されるので、上の例の場合は伝播させるとログがコンソールに 2 つずつ出てくる。ただ、app のほうでレベルに INFO を指定しているので、DEBUG 出力は上位にも行かず、どこにも出てこないことになる。 もし、app 以外の適当な名前でロガーを作成した場合は、root の設定が用いられる。 ログローテーションlog_test4.py
import logging
from logging.handlers import TimedRotatingFileHandler
import os
def setup_daily_logger(name, log_dir='logs'):
# ログディレクトリの作成
os.makedirs(log_dir, exist_ok=True)
logger = logging.getLogger(name)
logger.setLevel(logging.INFO)
# 日付ごとのローテーションハンドラー
handler = TimedRotatingFileHandler(
filename=os.path.join(log_dir, 'app.log'),
when='midnight', # 毎日午前0時にローテーション
interval=1, # 1日間隔
backupCount=30, # 30日分のバックアップを保持
encoding='utf-8'
)
# ログファイル名にタイムスタンプを追加
handler.suffix = '%Y%m%d'
formatter = logging.Formatter(
'%(asctime)s.%(msecs)03d - %(name)s - %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger
logger = setup_daily_logger(__name__)
logger.info("アプリケーションが開始されました")
logs ディレクトリが作成され、中に app.log ができる。古いものは "app.log.20250710" といった名前になる。 logging2.conf
[loggers]
keys=root,app
[handlers]
keys=consoleHandler,fileHandler
[formatters]
keys=simpleFormatter
[logger_root]
level=DEBUG
handlers=consoleHandler
[logger_app]
level=INFO
handlers=consoleHandler,fileHandler
qualname=app
propagate=0
[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)
[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=simpleFormatter
args=('app.log', 'a', 'utf-8')
[formatter_simpleFormatter]
format=%(asctime)s.%(msecs)03d - %(name)s - %(levelname)s - %(message)s
datefmt=%Y-%m-%d %H:%M:%S
CSV 出力CSV で出力したい場合は、次のようにする。 logging3.conf
[loggers]
keys=root,app
[handlers]
keys=consoleHandler,timedRotatingFileHandler
[formatters]
keys=csvFormatter
[logger_root]
level=DEBUG
handlers=consoleHandler
[logger_app]
level=INFO
handlers=consoleHandler,timedRotatingFileHandler
qualname=app
propagate=0
[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=csvFormatter
args=(sys.stdout,)
[handler_timedRotatingFileHandler]
class=logging.handlers.TimedRotatingFileHandler
level=DEBUG
formatter=csvFormatter
args=('logs/app.csv', 'midnight', 1, 30, 'utf-8')
[formatter_csvFormatter]
format="%(asctime)s.%(msecs)03d","%(name)s","%(levelname)s","%(message)s"
datefmt=%Y-%m-%d %H:%M:%S
| |
| PENGUINITIS | |