アプリケーションを開発・運用する際、ログ情報は非常に重要です。開発中はコンソール(画面)でリアルタイムに動作を確認したい一方で、本番運用時や後からエラー解析を行うためには、ログを「ファイル」として永続的に保存しておく必要があります。
Pythonの logging モジュールでは、**「ハンドラ(Handler)」**という仕組みを使うことで、ログの出力先を自由に制御できます。
この記事では、StreamHandler(コンソール用)と FileHandler(ファイル用)を組み合わせ、ログを画面とファイルの両方に出力する方法について解説します。
ログハンドラとは
ハンドラは、「ロガーが生成したログメッセージを、適切な出力先(ファイル、コンソール、メールなど)に送る」役割を持つコンポーネントです。
代表的なハンドラには以下の2つがあります。
logging.StreamHandler(): 標準出力(コンソール/ターミナル)にログを出力します。logging.FileHandler("ファイル名"): 指定したファイルにログを出力(保存)します。デフォルトでは追記モードで書き込まれます。
これらを logging.basicConfig の handlers 引数にリストとして渡すことで、複数の出力先を同時に設定できます。
実装例:画面表示とファイル保存の同時実行
システム起動処理を模したログを、画面に表示しつつ system.log というファイルにも保存するコードを作成します。
import logging
# 1. ログのフォーマット定義
# 日時 - ロガー名 - レベル - メッセージ
log_format = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
# 2. ハンドラの作成
# コンソール出力用
stream_handler = logging.StreamHandler()
# ファイル出力用 (system.log に保存)
file_handler = logging.FileHandler("system.log", encoding="utf-8")
# 3. ログの基本設定 (basicConfig)
# handlers 引数に作成したハンドラのリストを渡す
logging.basicConfig(
level=logging.DEBUG,
format=log_format,
handlers=[stream_handler, file_handler]
)
# 4. ロガーの取得とログ出力実行
logger = logging.getLogger(__name__)
logger.info("システム初期化を開始します。")
logger.debug("設定ファイル config.ini を読み込み中...")
logger.warning("推奨されない設定が見つかりました: timeout=0")
try:
# エラー発生のシミュレーション
process_result = 10 / 0
except ZeroDivisionError:
logger.error("重大なエラーが発生しました: ゼロ除算", exc_info=True)
logger.info("システムを終了します。")
実行結果の確認
このスクリプトを実行すると、以下の2つの結果が得られます。
1. コンソール(画面)の出力
ターミナルにはリアルタイムでログが表示されます。
2025-11-29 15:00:01,123 - __main__ - INFO - システム初期化を開始します。
2025-11-29 15:00:01,124 - __main__ - DEBUG - 設定ファイル config.ini を読み込み中...
2025-11-29 15:00:01,125 - __main__ - WARNING - 推奨されない設定が見つかりました: timeout=0
2025-11-29 15:00:01,126 - __main__ - ERROR - 重大なエラーが発生しました: ゼロ除算
Traceback (most recent call last):
...
ZeroDivisionError: division by zero
2025-11-29 15:00:01,127 - __main__ - INFO - システムを終了します。
2. ログファイル(system.log)の中身
スクリプトと同じディレクトリに system.log が作成され、コンソールと同じ内容が書き込まれています。
2025-11-29 15:00:01,123 - __main__ - INFO - システム初期化を開始します。
2025-11-29 15:00:01,124 - __main__ - DEBUG - 設定ファイル config.ini を読み込み中...
2025-11-29 15:00:01,125 - __main__ - WARNING - 推奨されない設定が見つかりました: timeout=0
2025-11-29 15:00:01,126 - __main__ - ERROR - 重大なエラーが発生しました: ゼロ除算
Traceback (most recent call last):
...
ZeroDivisionError: division by zero
2025-11-29 15:00:01,127 - __main__ - INFO - システムを終了します。
まとめ
logging モジュールで出力先を制御するポイントは以下の通りです。
StreamHandler: 画面出力用。FileHandler: ファイル保存用。basicConfig(handlers=[...]): 複数のハンドラをリストで渡すことで、一度のログ出力命令で複数の場所にログを記録できます。
これにより、「開発中は画面で確認し、運用時はファイルに残す(あるいは両方行う)」といった柔軟な運用が可能になります。
