Pythonでプログラムを作っていると、途中の状態やエラーを記録しておきたくなることがあります。
そんなときに使えるのが logging
モジュールです。
今回は、自分の学習のために、Pythonのログ出力について基本から丁寧に整理してみました。
print()
との違いやログレベルの使い方、ロガーの仕組み、カスタマイズ方法まで一通りまとめています。
ログとは?
ログとは、プログラムの実行中に起きた出来事を記録するものです。
以下のような場面で役立ちます。
- 処理の進行状況を記録しておきたいとき
- エラーが起きた場所や原因を調べたいとき
- 後から動作を再確認したいとき
ログは「記録」なので、ユーザーに見せるメッセージとは別です。
主に開発者や運用担当者が、あとからシステムの状態を把握するために使います。
print()
と logging
の違い
Pythonでログのように情報を出力する方法として、print()
も使えます。
ただし print()
には次のような限界があります。
項目 | print() |
logging |
---|---|---|
表示レベルの切り替え | ❌ できない | ✅ ログレベルで制御できる |
ファイル出力 | ❌ 標準出力のみ | ✅ ファイル保存できる |
フォーマット指定 | ❌ 手動で整形が必要 | ✅ 専用の書式指定がある |
本番環境での利用 | ❌ 推奨されない | ✅ 安定した標準手法 |
開発中の簡単な確認には print()
でも十分ですが、
本格的なログ出力や運用時の記録には logging
を使う方が安全で便利です。
ログレベルとは?(5つのレベル)
logging
モジュールでは、ログの「重要度」を5段階で表します。
これを ログレベル(ログのレベル分け) と呼びます。
レベル | 意味 | 主な用途 |
---|---|---|
DEBUG |
開発者向けの詳細情報 | 変数の中身・処理の途中経過など |
INFO |
通常の動作記録 | 処理開始・成功メッセージなど |
WARNING |
注意喚起 | 将来的なエラーの可能性など |
ERROR |
エラー発生 | 例外処理や失敗時の記録 |
CRITICAL |
致命的なエラー | サービス停止レベルの重大問題 |
設定したログレベル以上のログだけが出力される仕組みになっています。
basicConfig()
を使った最も基本的な使い方
まずは一番シンプルなログ出力です。
import logging
logging.basicConfig(level=logging.INFO)
logging.debug("これはデバッグメッセージ")
logging.info("これは情報メッセージ")
logging.warning("これは警告メッセージ")
logging.error("これはエラーメッセージ")
logging.critical("これは致命的なエラーメッセージ")
解説:
-
basicConfig()
はログ全体の設定をする関数です。 -
level=logging.INFO
にすると、INFO
以上のログ(INFO, WARNING, ERROR, CRITICAL)が出力されます。 -
DEBUG
はそれより下のレベルなので出力されません。
ロガー(logger)とは?【補足:とても大事な概念】
ここで出てくる「ロガー(logger)」という言葉が何を意味するのか、補足しておきます。
✅ ロガーとは?
ロガーは、**ログを出力するための「窓口」や「担当者」**のようなものです。
logger.info("〇〇しました")
のように、ログを出したいときは常にロガーを通して出力します。
✅ なぜロガーが必要?
ロガーがあることで、次のようなことができます:
- ログの出力レベルを制御できる
- 出力先を自由に設定できる(画面・ファイルなど)
- モジュールごとに分けて整理できる(後述)
✅ 実際にロガーを使うコード
import logging
logger = logging.getLogger(__name__) # ロガーの取得
logger.setLevel(logging.INFO)
logger.info("ロガーを通してログを出力しています")
これで「ロガーを通してログを出す」という意味が分かってきます。
ログ出力の形式を指定する(format指定)
import logging
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s"
)
logging.info("ログにタイムスタンプを追加")
ログをファイルに出力する(filename指定)
import logging
logging.basicConfig(
filename="logfile.txt",
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s"
)
logging.info("これはファイルに出力されるログです")
モジュールごとにロガーを分ける(getLogger)
大きなプログラムでは、ファイル(モジュール)ごとにロガーを分けて使うのが定番です。
こうすることで、どのモジュールから出力されたログかを自動で識別できます。
例:module1.py
import logging
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
def say_hello():
logger.info("module1 からのログです")
例:main.py
import logging
import module1
logging.basicConfig(
level=logging.INFO,
format="%(name)s - %(levelname)s - %(message)s"
)
module1.say_hello()
実行結果(例)
module1 - INFO - module1 からのログです
複数出力や細かいカスタマイズ(応用編)
たとえば、ファイルにはすべて記録、画面には警告以上だけという使い分けも可能です。
import logging
logger = logging.getLogger("my_logger")
logger.setLevel(logging.DEBUG)
file_handler = logging.FileHandler("full.log")
file_handler.setLevel(logging.DEBUG)
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.WARNING)
formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
file_handler.setFormatter(formatter)
console_handler.setFormatter(formatter)
logger.addHandler(file_handler)
logger.addHandler(console_handler)
logger.debug("DEBUGログ(ファイルのみ)")
logger.warning("WARNINGログ(両方に出力)")
おわりに
今回は、Pythonの logging
モジュールについて、ロガーの仕組みを含めて丁寧にまとめてみました。
最初は print()
を使っていましたが、ログの仕組みを理解してからは logging
の方が整理しやすく、柔軟に管理できると感じました。
これからも実際のコードで使いながら、慣れていこうと思います。