開発中のデバッグや、本番環境での動作確認において、「プログラムがどこまで進んだか」「変数の値はどうなっているか」を確認するために print() 関数を使用することはよくあります。
しかし、本格的なアプリケーション開発においては、print() ではなく標準ライブラリの logging モジュールを使用することが強く推奨されます。
この記事では、logging モジュールの基本的な使い方、ログレベルの概念、そして出力フォーマットの設定方法について解説します。
なぜ print() ではなく logging なのか
print() 関数と比較して、logging モジュールには以下のような利点があります。
- ログレベルによる制御: 重要度(エラー、警告、情報など)に応じて、出力するログを簡単にフィルタリングできます(例:本番環境ではデバッグ情報を出さない)。
- 出力先の変更: 標準出力(コンソール)だけでなく、ファイルへの保存やメール送信など、出力先(ハンドラ)を柔軟に変更できます。
- フォーマットの統一: 日時、ファイル名、行番号などのメタ情報を自動的に付与し、ログの形式を統一できます。
ログレベルの理解
logging モジュールには、重要度の低い順に5つのログレベルが定義されています。設定したレベル以上のログが出力されます。
| レベル | 定数名 | 数値 | 用途 |
| DEBUG | logging.DEBUG | 10 | 開発中の詳細な情報。動作確認用。 |
| INFO | logging.INFO | 20 | 正常な動作の報告。処理の開始・終了など。 |
| WARNING | logging.WARNING | 30 | 想定外だが実行可能な問題。警告。 |
| ERROR | logging.ERROR | 40 | 重大な問題により機能を実行できない場合。 |
| CRITICAL | logging.CRITICAL | 50 | プログラム自体が停止するような致命的なエラー。 |
デフォルトの設定では WARNING 以上 のログのみが出力され、INFO や DEBUG は無視されます。
基本的な実装例
それでは、実際に logging モジュールを使ってログを出力するコードを作成します。
ここでは、basicConfig を使って全体のログ設定を行い、getLogger(__name__) でモジュール専用のロガーを取得するという、最も標準的なパターンを紹介します。
import logging
# 1. ログの基本設定
# level: 出力する最低レベルを指定 (ここではINFO以上)
# format: ログの出力形式を指定 (日時 - ロガー名 - レベル - メッセージ)
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
# 2. ロガーの取得
# __name__ を渡すことで、どのモジュールからのログかを識別しやすくする
logger = logging.getLogger(__name__)
def perform_task(task_id):
# 情報レベルのログ (出力される)
logger.info(f"タスク {task_id} の処理を開始します。")
# デバッグレベルのログ (INFO設定なので出力されない)
logger.debug(f"タスク {task_id} の詳細デバッグ情報...")
if task_id < 0:
# エラーレベルのログ (出力される)
logger.error("タスクIDが不正です。処理を中断します。")
return
# 警告レベルのログ (出力される)
if task_id > 1000:
logger.warning("タスクIDが大きすぎます。処理に時間がかかる可能性があります。")
logger.info(f"タスク {task_id} が完了しました。")
# --- 実行 ---
print("--- 処理実行 ---")
perform_task(10)
print("\n--- エラー発生ケース ---")
perform_task(-1)
実行結果:
--- 処理実行 ---
2025-11-29 10:30:05,123 - __main__ - INFO - タスク 10 の処理を開始します。
2025-11-29 10:30:05,123 - __main__ - INFO - タスク 10 が完了しました。
--- エラー発生ケース ---
2025-11-29 10:30:05,124 - __main__ - INFO - タスク -1 の処理を開始します。
2025-11-29 10:30:05,124 - __main__ - ERROR - タスクIDが不正です。処理を中断します。
コードの解説
- logging.basicConfig(…):ログシステムの初期設定を行います。level=logging.INFO としたため、logger.debug() の内容は出力されていません。
- format=”…”:ログの出力形式を指定しています。
%(asctime)s: 日時%(name)s: ロガー名(ここでは__name__なので__main__)%(levelname)s: ログレベル名(INFO, ERRORなど)%(message)s: ログメッセージ本文
- logging.getLogger(__name__):ロガーオブジェクトを作成します。引数にモジュール名(__name__)を渡すのが慣例です。これにより、ログがどのファイルから出力されたかが明確になります。
ログをファイルに出力する(ハンドラ)
画面に表示するのではなく、ファイルに保存したい場合は、basicConfig に filename 引数を追加するだけで実現できます。
logging.basicConfig(
filename="app.log", # 出力するファイル名
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s"
)
これを実行すると、コンソールには何も表示されなくなり、代わりに実行ディレクトリに app.log というファイルが作成され、そこにログが追記されます。
まとめ
- ログ出力には
print()ではなくloggingモジュールを使用します。 - 5つのログレベル(DEBUG, INFO, WARNING, ERROR, CRITICAL)を使い分けます。
logging.basicConfig()でレベルやフォーマットを一括設定できます。logger = logging.getLogger(__name__)でロガーインスタンスを作成して使用します。
