Pythonのロギング(logging)入門。print卒業!プロが使うログ出力の正しい作法
プログラミングを始めたばかりの頃、動作確認のために print() 関数を多用していませんか?
変数の中身を表示したり、処理がどこまで進んだかを確認したりするのに、print() は非常に手軽で便利な道具です。
しかし、エンジニアとして実務レベルのコードを書くようになると、この print() への依存が思わぬトラブルを招くことがあります。
本番環境で動くプログラムにおいて、動作の記録を残すための正解は print() ではなく「ロギング」という仕組みを使うことです。
私はエンジニアとして10年ほど活動していますが、初心者が書いたコードをレビューする際、最初のアドバイスとして「ログを出力しよう」と伝えることが多々あります。
今回は、なぜプロは print() を卒業するのか、そしてPython標準の logging モジュールをどのように使いこなすべきかを徹底解説します。
なぜ print() を卒業してロギングを使うのか¶
そもそも、なぜ print() ではいけないのでしょうか?
手元のパソコンで小さなスクリプトを動かすだけなら問題ありませんが、サーバーで24時間動くようなシステムでは事情が変わります。
print() で出力した情報は、プログラムが終了すると消えてしまったり、他の出力と混ざってしまったりして、後から追いかけるのが非常に困難です。
ロギングを導入することで、プログラムが「いつ」「どこで」「どのような重要度で」動いたのかを正確に記録できるようになります。
ログは「未来の自分」へのメッセージ¶
プログラムをリリースした後、深夜に突然エラーが発生した場面を想像してみてください。 そのとき、手元に「エラー直前の変数の状態」や「処理の経過時間」が記録されたログがあれば、原因特定は一瞬で終わります。
もしログがなければ、あなたは真っ暗な部屋で落としたコンタクトレンズを探すような、果てしないデバッグ作業を強いられることになるでしょう。 エンジニア歴10年の経験から断言できるのは、良いログを書くことは、未来の自分を救う最大の投資であるということです。
print() にはできないロギングの強み¶
ロギングには print() にはない高度な機能が備わっています。
例えば、重要度に応じて出力内容をフィルタリングしたり、出力先をコンソールだけでなくファイルや外部サーバーへ自動で切り替えたりすることが可能です。
また、ログには標準で出力時刻やファイル名、行番号などを付与できるため、デバッグの効率が劇的に向上します。 次に、ロギングを使いこなす上で最も重要な概念である「ログレベル」について見ていきましょう。
1. ログレベルを理解する:重要度の仕分け¶
ロギングには、出力する情報の重要度を表すログレベルという概念があります。 すべての情報を同じ重みで出力してしまうと、本当に重要なエラー情報が埋もれてしまうからです。
Pythonの logging モジュールでは、標準で5段階のレベルが用意されています。
それぞれの役割を正しく理解し、適切に使い分けることがプロへの第一歩です。
| レベル名 | 数値 | 用途の目安 |
|---|---|---|
| DEBUG | 10 | 開発中のデバッグ用。変数の中身など詳細な情報 |
| INFO | 20 | 正常動作の確認。処理の開始や終了など |
| WARNING | 30 | 注意喚起。放っておくとエラーになる可能性がある事象 |
| ERROR | 40 | 重大な問題。特定の処理が失敗したとき |
| CRITICAL | 50 | 致命的な問題。プログラム全体が停止するような事象 |
レベルを使い分けるメリット¶
例えば、開発中は DEBUG レベルまですべて出力し、本番環境では INFO 以上のみを出力するといった切り替えが簡単にできます。 コードを一行も書き換えることなく、設定一つで情報の密度をコントロールできるのがロギングの醍醐味です。
初心者のうちは、何でもかんでも print() してしまいがちですが、これからは「これは警告だから WARNING だな」と一歩立ち止まって考えてみてください。
この習慣がつくだけで、あなたのコードの品質は格段に向上します。
【関連記事】:Pythonの例外処理のアンチパターン5選をご紹介!|初心者がやりがちな「べからず集」
2. Pythonでの基本的なロギングの実装方法¶
それでは、実際にPythonでログを出力してみましょう。
Pythonには logging という標準ライブラリが最初から組み込まれているため、追加のインストールは不要です。
まずは、最もシンプルな形での出力方法を確認します。 以下のコードをエディタにコピーして実行してみてください。
import logging
# 基本設定:INFOレベル以上のログを表示するように設定
logging.basicConfig(level=logging.INFO)
# 各レベルでログを出力
logging.debug("これは表示されません(レベルが低いため)")
logging.info("処理を開始しました")
logging.warning("少し注意が必要な状態です")
logging.error("エラーが発生しました")
logging.critical("致命的なエラーです")
basicConfig の役割¶
logging.basicConfig() は、ロギングの挙動を一度に設定するための便利な関数です。
ここで level=logging.INFO と指定することで、INFOより重要度が低い DEBUG ログは無視されるようになります。
つなぎとして、もし設定を記述せずに実行すると、デフォルトでは WARNING 以上しか表示されない点に注意してください。 これは、重要度の低いログでコンソールが埋まってしまうのを防ぐための親切な設計です。
3. ログをファイルに保存する:実務での必須テクニック¶
プログラムを実行するたびにコンソールを確認するのは大変ですよね。 実務では、ログをファイルに書き出して後から分析できるようにするのが一般的です。
ファイル出力の設定方法¶
ファイルへの保存も、basicConfig の引数を少し変えるだけで簡単に実現できます。
filename 引数に出力先のファイル名を指定してみましょう。
import logging
# ログを「app.log」というファイルに保存する設定
logging.basicConfig(
filename='app.log',
filemode='w', # 'w'は上書き、'a'は追記(デフォルトは'a')
level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logging.info("ファイルへのロギングテストを開始します")
logging.error("何か問題が起きたようです")
フォーマットを指定して見やすくする¶
上記のコードでは format という引数を使っています。
これを使うことで、「何時に」「どのレベルで」「どんなメッセージが」出たのかを整形して記録できます。
プロの現場では、このフォーマットにプロセスIDや実行している関数名を含めることもあります。 情報を整理して記録することで、数千行あるログの中から必要な情報を探すのが驚くほど楽になります。
【関連記事】:綺麗なコードって何?初心者から一歩抜け出す「リーダブルコード」の3つの基本
4. 例外(エラー)をログに記録する正しい作法¶
プログラムがクラッシュした際、単に「エラーが起きました」とだけ記録されていても、原因はわかりません。 Pythonのロギングには、エラーが発生した際の詳細な足跡(トレースバック)をそのまま記録する機能があります。
logging.exception の魔術¶
例外処理の except ブロックの中で logging.exception() を使うのが、プロの定石です。
これを使うと、わざわざ自分でエラー内容を文字列にしなくても、発生したエラーの全容を自動でキャプチャしてくれます。
import logging
logging.basicConfig(level=logging.ERROR)
try:
# 意図的にエラーを発生させる(0での割り算)
result = 10 / 0
except ZeroDivisionError:
# exceptionメソッドを使うと、エラーの詳細(トレースバック)が自動で記録される
logging.exception("計算中にエラーが発生しました")
なぜ exception メソッドなのか¶
通常の logging.error() でもメッセージは出せますが、exception() を使うと「どのファイルの何行目でエラーが起きたか」という情報まで詳しく残してくれます。
この情報があるだけで、バグ修正のスピードは10倍変わると言っても過言ではありません。
エンジニア歴10年の私がこれまで見てきた中で、トラブル解決が速い人ほど、この詳細なログを重宝しています。 エラーを隠すのではなく、詳細にさらけ出すことが、結果として堅牢なシステムを作る近道になります。
5. ロギングを運用する上でのプロの心得¶
文法を覚えるのは簡単ですが、何をログに出すべきかを判断するのは少し経験が必要です。 ここでは、私が現場で意識している「ログ設計」のポイントをいくつか紹介します。
多すぎればノイズになり、少なすぎれば手がかりにならない。 そんなログの「ちょうど良さ」を見つけるヒントにしてください。
個人情報は絶対に出さない¶
ログには、ユーザーのパスワードやクレジットカード番号などの機密情報を絶対に出力してはいけません。 ログファイルは多くの開発者が目にすることもあり、万が一流出した際のリスクが非常に高いためです。
デバッグのために一時的にユーザーIDを出すことはあっても、本番環境に残らないよう細心の注意を払いましょう。 「安全なログ」を書くことも、プロエンジニアに求められる重要な倫理観です。
意味のあるメッセージを心がける¶
「ここを通った」「OK」といった、後から見て意味のわからないログは避けましょう。 「ユーザー(ID: 123)の決済処理を開始しました」のように、状況が具体的にわかるメッセージを書くのがコツです。
AIを使ってコードを書く際も、AIが出した曖昧なログメッセージを自分なりに具体化する習慣をつけてください。 AIが出したコードが本当に正しいのか、ログを見ながら対話するように確認する姿勢が大切です。
【関連記事】:AIが提案するコード、信じていい? AIのミスを見抜くための審美眼
まとめ:今日から print() を卒業しよう¶
ロギングは、一見すると print() よりも少し手間がかかるように感じるかもしれません。
しかし、そのわずかな手間が、将来のあなたを大きな苦労から救い出してくれることになります。
- ログレベルを適切に使い分け、情報の重要度を整理する。
- basicConfig を活用して、コンソールやファイルへの出力をコントロールする。
- logging.exception でエラーの詳細を逃さずキャッチする。
- 個人情報の出力に気をつけ、意味のあるメッセージを残す。
これらのポイントを意識するだけで、あなたのプログラムは「個人の趣味のコード」から「プロが扱う信頼性の高いシステム」へと進化します。
まずは今書いているコードの print() を一つ、logging.info() に書き換えるところから始めてみましょう。
一歩ずつ「正しい作法」を身につけて、より快適なPythonライフを送ってください。
ここまでお読みいただきありがとうございました!