Pythonでプログラムを書いていて、動作確認のために print() をあちこちに散りばめていませんか?最初のうちはそれで十分ですが、プログラムの規模が大きくなってくると、「どこで・いつ・どんな深刻度で何が起きたのか」を整理して残しておく仕組みが必要になります。
そこで登場するのが、Python標準ライブラリの logging モジュール。これを使いこなせるようになると、ちょっとしたスクリプトが一気に「現場で使える堅牢なツール」へと進化します✨ バグの原因究明も、運用中のトラブル対応も、驚くほど楽になりますよ。
ログとは、プログラムの動作状況を記録した「足跡」のようなもの。Pythonでエラーが出たときに表示されるメッセージや、pip install 実行時にズラッと流れる進捗メッセージも、すべてログの一種です。
ログがあると、こんなときに大助かりします。
「動いているからOK」ではなく「後から振り返れる状態」を作ること——それがプロのコーディングへの第一歩です💡
ログを残すだけなら print() でもできるのに、なぜ logging を使うのか?答えはシンプルで、ログ出力に特化した便利機能が満載だからです。
これらすべてを print() で再現しようとすると地獄です。最初から logging を使う癖をつけておきましょう👌
loggingモジュールを理解するコツは、3つの登場人物を押さえること。
この3つが連携することで、柔軟なログ出力が実現します。
from logging import getLogger, StreamHandler, DEBUG
# 1. ロガーを作成
logger = getLogger(__name__)
logger.setLevel(DEBUG)
# 2. ハンドラーを作成(標準出力に出すタイプ)
handler = StreamHandler()
handler.setLevel(DEBUG)
# 3. ロガーにハンドラーをセット
logger.addHandler(handler)
# 4. ログを出力!
logger.debug("これはデバッグログです")
たった数行ですが、これでもう print() より一段上のログ出力が完成です🎉
getLogger(__name__) の __name__ はPythonの特殊な変数で、そのファイルのモジュール名が自動で入ります。直接実行されたときは "__main__"、importされたときはモジュール名になります。「とりあえずおまじないとして書く」で最初はOKです。
Pythonのloggingには、5段階のログレベルが用意されています。下にいくほど重大度が高いと覚えましょう。
ロガーには各レベルに対応した同名のメソッドがあります。
logger.debug("デバッグ情報")
logger.info("正常動作中")
logger.warning("注意が必要です")
logger.error("エラーが発生しました")
logger.critical("致命的な問題です")
ロガーとハンドラーの両方にレベルを設定する必要があり、両方の条件を満たさないと出力されません。
これは一見ややこしく感じますが、後で説明する「複数のハンドラーを使い分ける」ときに威力を発揮します💪
ただログが出るだけでは「いつ・どこで・何が起きたか」が分かりにくいですよね。Formatterを使うと、ログに自動で情報を付け足せます。
from logging import Formatter
formatter = Formatter("[%(levelname)s] %(asctime)s %(message)s (%(filename)s)")
handler.setFormatter(formatter)
よく使うプレースホルダはこちら。
%(levelname)s:ログレベル(DEBUG/INFOなど)%(asctime)s:ログ出力時刻%(message)s:ログメッセージ本文%(filename)s:ログ出力コードが書かれたファイル名%(funcName)s:関数名%(lineno)d:行番号これだけで、出力結果が一気に「プログラムのログらしい」見た目に変わります。
[ERROR] 2026-05-10 14:32:15,123 エラーが発生しました (app.py)
画面に流すだけでは、後で振り返ることができません。FileHandler を使えば、ログをファイルに保存できます。
from logging import FileHandler
file_handler = FileHandler("log.txt")
file_handler.setLevel(DEBUG)
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
logger.error("ファイルにも記録されます")
実行すると log.txt が生成され、再実行するごとに追記モードでログが溜まっていきます📚 サーバーで動かすスクリプトの定石です。
ハンドラーは複数登録できるので、こんな使い分けが可能です。
# 全レベルを log_all.txt に
all_handler = FileHandler("log_all.txt")
all_handler.setLevel(DEBUG)
# ERROR以上だけ error.txt に
error_handler = FileHandler("error.txt")
error_handler.setLevel(ERROR)
logger.addHandler(all_handler)
logger.addHandler(error_handler)
これで、普段は log_all.txt でじっくり追跡、急ぎの障害対応では error.txt だけ確認、という運用が一発で実現します✨ ロガーとハンドラーの両方にレベルがあるのは、まさにこのためなんです。
ログ設計は「動かしてみて、調整して、また動かす」を繰り返すうちに身につく分野。お気に入りの書籍と快適な作業環境を揃えれば、Python中級者への階段が一段ずつ確実に上がっていきます。
「ロギングを利用せよ」「printを残すな」など、本稿の内容と直結するベストプラクティスが90項目で整理されています。プロが書くPythonに近づきたいすべての方に。
言語仕様だけでなく、Git・テスト・ロギングなど「現場で必要になる周辺知識」が網羅された一冊。本稿のloggingと組み合わせて学ぶと、ぐっと実践力が上がります。
定期実行スクリプトやWebスクレイピングなど、ログが本当に役立つ実例が満載。「学んだloggingをすぐ生活に応用したい!」という方にぴったりです。
ログ設定はトライ&エラーが多いので、打鍵感のいいキーボードがあると作業効率が段違い。静音設計でバックライト付き、夜の学習も気持ちよく続けられます。
左にコード、右にログ出力やファイルを並べておくと、loggingの挙動を確認しながらの開発がスムーズに。USB-C一本接続できるモデルはノートPC学習者の強い味方です。
print() は単に画面に出すだけですが、logging はレベルでフィルタ・複数の出力先・自動的な時刻付与などができます。本番環境ではログだけ抑制したり、開発中だけ詳細を出したりが一発で切り替えられるのが最大の違いです。
前者はルートロガー(モジュール直下のロガー)に対する操作で、後者は getLogger() で取得した特定のロガーへの操作です。規模が大きくなるほど後者の方が管理しやすいため、最初から logger = getLogger(__name__) で書く癖をつけるのがおすすめです。
ハンドラーを誤って2回追加した、または親ロガーにもハンドラーが設定されているなどが原因です。logger.handlers.clear() で一度クリアしてから設定し直すと解決することが多いです。
標準ライブラリの RotatingFileHandler や TimedRotatingFileHandler を使うと、ファイルサイズや日付で自動的にログファイルを切り替えてくれます。長期運用するスクリプトでは必須テクニックです🔁
logging.basicConfig() を使うと、ハンドラーやフォーマッタの設定をワンライナーで済ませられます。試作段階やシンプルなスクリプトならこれで十分。複雑な要件が出てきたら本稿のように手動で組み立てるとよいでしょう。
Pythonの logging モジュールは、最初こそ「ロガー・ハンドラー・フォーマッタ…登場人物が多くて難しい!」と感じるかもしれません。でも、「命令する人・出力する人・整える人」という役割分担さえ押さえれば、驚くほどスッキリ理解できます。
5段階のログレベルを使い分け、用途に応じて画面とファイルへ振り分け、時刻やファイル名を自動で付与する——これだけで、あなたのコードは「動くだけ」から「運用に耐えるツール」へと進化します🚀
すぐに完璧に理解する必要はありません。まずは「logger = getLogger(__name__) を書く」「logger.info() でメッセージを残す」という小さな一歩から始めてみてください。お気に入りの書籍と快適な作業環境を味方につけて、Python中級者への階段を一段ずつ確実に上がっていきましょう📝✨