📝 「print文だらけのコード」、卒業しませんか?
Pythonでプログラムを書いていて、動作確認のために print() をあちこちに散りばめていませんか?最初のうちはそれで十分ですが、プログラムの規模が大きくなってくると、「どこで・いつ・どんな深刻度で何が起きたのか」を整理して残しておく仕組みが必要になります。
そこで登場するのが、Python標準ライブラリの logging モジュール。これを使いこなせるようになると、ちょっとしたスクリプトが一気に「現場で使える堅牢なツール」へと進化します✨ バグの原因究明も、運用中のトラブル対応も、驚くほど楽になりますよ。
📦 そもそもログって何?なぜ重要なの?
ログとは、プログラムの動作状況を記録した「足跡」のようなもの。Pythonでエラーが出たときに表示されるメッセージや、pip install 実行時にズラッと流れる進捗メッセージも、すべてログの一種です。
ログがあると、こんなときに大助かりします。
- 🐛 バグの原因究明:どこで何が起きたか時系列で追える
- 🛠 開発中の動作確認:想定通りに動いているか確かめられる
- 🚨 運用中のトラブル対応:エラーの兆候を見逃さない
- 📊 利用状況の把握:どの機能がよく使われているか分析できる
「動いているからOK」ではなく「後から振り返れる状態」を作ること——それがプロのコーディングへの第一歩です💡
🤔 print文じゃダメなの?
ログを残すだけなら print() でもできるのに、なぜ logging を使うのか?答えはシンプルで、ログ出力に特化した便利機能が満載だからです。
- 📊 ログレベル(重要度)で出力をコントロールできる
- 📁 出力先を画面・ファイル・複数同時など自由に切り替えられる
- 🕒 時刻・ファイル名・関数名などを自動で付与できる
- 🎚 本番環境ではエラーだけ、開発中は全部、と切り替えが一発
これらすべてを print() で再現しようとすると地獄です。最初から logging を使う癖をつけておきましょう👌
🚀 loggingの基本構造:3つの登場人物
loggingモジュールを理解するコツは、3つの登場人物を押さえること。
- ロガー(Logger):「こんなログを出してね」と命令する人📣
- ハンドラー(Handler):実際にログをどこに出力するかを担当する人📤
- フォーマッタ(Formatter):ログの見た目を整える人🎨
この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() より一段上のログ出力が完成です🎉
🤖 __name__ ってなに?
getLogger(__name__) の __name__ はPythonの特殊な変数で、そのファイルのモジュール名が自動で入ります。直接実行されたときは "__main__"、importされたときはモジュール名になります。「とりあえずおまじないとして書く」で最初はOKです。
🎚 5段階のログレベルを使い分ける
Pythonのloggingには、5段階のログレベルが用意されています。下にいくほど重大度が高いと覚えましょう。
- 🔍 DEBUG:開発中の動作確認用。詳細な情報を記録
- ℹ️ INFO:正常な動きの記録。「処理が始まりました」など
- ⚠️ WARNING:想定外の事象や、問題が起きるかもしれない警告
- ❌ ERROR:問題が発生したときのログ
- 🚨 CRITICAL:システム停止級の重大な問題
ロガーには各レベルに対応した同名のメソッドがあります。
logger.debug("デバッグ情報")
logger.info("正常動作中")
logger.warning("注意が必要です")
logger.error("エラーが発生しました")
logger.critical("致命的な問題です")
🎛 レベル設定の重要なルール
ロガーとハンドラーの両方にレベルを設定する必要があり、両方の条件を満たさないと出力されません。
- ロガーが「ERROR以上だけ扱う」と設定 → DEBUG/INFOは弾かれる
- ロガーが「DEBUG以上OK」でも、ハンドラーが「ERROR以上だけ」なら画面には出ない
これは一見ややこしく感じますが、後で説明する「複数のハンドラーを使い分ける」ときに威力を発揮します💪
🎨 フォーマッタで見やすいログに整える
ただログが出るだけでは「いつ・どこで・何が起きたか」が分かりにくいですよね。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のログ運用力を伸ばすおすすめ学習アイテム
ログ設計は「動かしてみて、調整して、また動かす」を繰り返すうちに身につく分野。お気に入りの書籍と快適な作業環境を揃えれば、Python中級者への階段が一段ずつ確実に上がっていきます。
📖 中級者へのステップアップに最適な定番書
「ロギングを利用せよ」「printを残すな」など、本稿の内容と直結するベストプラクティスが90項目で整理されています。プロが書くPythonに近づきたいすべての方に。
🐍 現場で使えるPython運用術を学ぶ
言語仕様だけでなく、Git・テスト・ロギングなど「現場で必要になる周辺知識」が網羅された一冊。本稿のloggingと組み合わせて学ぶと、ぐっと実践力が上がります。
🛠 自動化スクリプトでloggingを活躍させたい方へ
定期実行スクリプトやWebスクレイピングなど、ログが本当に役立つ実例が満載。「学んだloggingをすぐ生活に応用したい!」という方にぴったりです。
⌨️ ログ設計を快適に進めるキーボード
ログ設定はトライ&エラーが多いので、打鍵感のいいキーボードがあると作業効率が段違い。静音設計でバックライト付き、夜の学習も気持ちよく続けられます。
🖥️ ログとコードを並べて見られる外部モニター
左にコード、右にログ出力やファイルを並べておくと、loggingの挙動を確認しながらの開発がスムーズに。USB-C一本接続できるモデルはノートPC学習者の強い味方です。
❓ よくある質問(FAQ)
🤔 print文と何が決定的に違うの?
print() は単に画面に出すだけですが、logging はレベルでフィルタ・複数の出力先・自動的な時刻付与などができます。本番環境ではログだけ抑制したり、開発中だけ詳細を出したりが一発で切り替えられるのが最大の違いです。
🆚 logging.debug() と logger.debug() は何が違う?
前者はルートロガー(モジュール直下のロガー)に対する操作で、後者は getLogger() で取得した特定のロガーへの操作です。規模が大きくなるほど後者の方が管理しやすいため、最初から logger = getLogger(__name__) で書く癖をつけるのがおすすめです。
📋 ログがダブって2回出力されてしまうのですが…
ハンドラーを誤って2回追加した、または親ロガーにもハンドラーが設定されているなどが原因です。logger.handlers.clear() で一度クリアしてから設定し直すと解決することが多いです。
🔄 ログファイルが大きくなりすぎたらどうする?
標準ライブラリの RotatingFileHandler や TimedRotatingFileHandler を使うと、ファイルサイズや日付で自動的にログファイルを切り替えてくれます。長期運用するスクリプトでは必須テクニックです🔁
🌐 もっと簡単に設定したい場合は?
logging.basicConfig() を使うと、ハンドラーやフォーマッタの設定をワンライナーで済ませられます。試作段階やシンプルなスクリプトならこれで十分。複雑な要件が出てきたら本稿のように手動で組み立てるとよいでしょう。
✨ まとめ:loggingで「後から助かる」コードを書こう
Pythonの logging モジュールは、最初こそ「ロガー・ハンドラー・フォーマッタ…登場人物が多くて難しい!」と感じるかもしれません。でも、「命令する人・出力する人・整える人」という役割分担さえ押さえれば、驚くほどスッキリ理解できます。
5段階のログレベルを使い分け、用途に応じて画面とファイルへ振り分け、時刻やファイル名を自動で付与する——これだけで、あなたのコードは「動くだけ」から「運用に耐えるツール」へと進化します🚀
すぐに完璧に理解する必要はありません。まずは「logger = getLogger(__name__) を書く」「logger.info() でメッセージを残す」という小さな一歩から始めてみてください。お気に入りの書籍と快適な作業環境を味方につけて、Python中級者への階段を一段ずつ確実に上がっていきましょう📝✨




































コメント