Python logging.error()とは?エラーを記録する方法
Pythonのlogging.error()は、処理が失敗したことを記録する関数です。
例外処理とセットで使うことが多く、トレースバックを一緒に残せるかが調査効率を大きく左右します。
logging.error()の基本的な使い方
import logging
logging.basicConfig(format="%(levelname)s: %(message)s")
try:
1 / 0
except ZeroDivisionError:
logging.error("計算に失敗しました")
実行結果:
ERROR: 計算に失敗しました
ERRORはWARNINGより上のレベルなので、設定なしでも表示されます。
これだけでは原因が分からない
上のログには重大な欠陥があります。「計算に失敗した」ことは分かりますが、なぜ失敗したのか、どこで失敗したのかが記録されていません。
調査するには、例外の中身が必要です。
logging.exception()でトレースバックを残す
import logging
logging.basicConfig(format="%(levelname)s: %(message)s")
try:
1 / 0
except ZeroDivisionError:
logging.exception("計算に失敗しました")
実行結果:
ERROR: 計算に失敗しました
Traceback (most recent call last):
File "<string>", line 5, in <module>
ZeroDivisionError: division by zero
トレースバックが付きました。ファイル名・行番号・例外の種類がすべて記録されます。
logging.exception()はレベルがERRORで、例外情報を自動で付けてくれる関数です。exceptブロックの中でしか使えません(外で呼ぶとNoneType: Noneと出ます)。
exc_info=Trueでも同じ
import logging
logging.basicConfig(format="%(levelname)s: %(message)s")
try:
1 / 0
except ZeroDivisionError:
logging.error("失敗", exc_info=True)
実行結果:
ERROR: 失敗
Traceback (most recent call last):
File "<string>", line 5, in <module>
ZeroDivisionError: division by zero
結果はexception()と同じです。
| 書き方 | 特徴 |
|---|---|
logging.exception(msg) |
短い。ERROR固定 |
logging.error(msg, exc_info=True) |
同じ結果。明示的 |
logging.warning(msg, exc_info=True) |
ERROR以外でも例外を残せる |
exc_info=Trueはどのレベルでも使えます。リトライ中の失敗をWARNINGで記録しつつ、原因も残したいときに便利です。
何をERRORに書くか
基準は「やろうとしたことが達成できなかった」かどうかです。
| ERRORに向くもの | 例 |
|---|---|
| 処理が失敗した | 「注文の保存に失敗」 |
| 再試行しても駄目だった | 「3回試して接続できず」 |
| 必須のデータがない | 「必要な設定項目が未定義」 |
| 外部サービスが応答しない | 「決済APIがタイムアウト」 |
逆に、代替手段で続行できたならWARNINGです。境界は「目的を達成できたか」で判断してください。
ログを出したあと、どうするか
よくある間違いが「ログを出して握りつぶす」ことです。
try:
save(order)
except Exception:
logging.exception("保存に失敗")
# ← 何もせず先へ進んでしまう
呼び出し元は成功したと思い込みます。ログには残りますが、誰も見なければ気づきません。
選択肢は3つです。
| 方針 | 書き方 |
|---|---|
| 呼び出し元に知らせる | ログを出してraiseで再送出 |
| この場で処理を終える | ログを出してsys.exit(1) |
| 意図的に続行する | なぜ続行してよいかをコメントで書く |
import logging
try:
save(order)
except Exception:
logging.exception("注文の保存に失敗: order_id=%s", order.id)
raise
ログを残しつつ、失敗は上に伝える——これが基本形です。
except Exceptionで全部受けない
try:
process()
except Exception:
logging.exception("エラー")
手軽ですが、想定していないバグまで飲み込みます。タイプミスによるNameErrorも同じ扱いになり、原因の切り分けが遅れます。
捕まえる例外は具体的に指定してください。
try:
process()
except (OSError, ValueError):
logging.exception("処理に失敗")
raise
追跡できる情報を入れる
logging.exception("保存に失敗") # 何の保存か不明
logging.exception("注文の保存に失敗: order_id=%s", oid) # 追跡できる
ERRORログは障害対応で真っ先に読まれます。「どのデータで」「どの処理が」失敗したかが分かるよう、識別子を必ず含めてください。
ただしパスワード・トークン・個人情報は書かない——これはどのレベルでも同じです。
5つのログレベル
| レベル | 数値 | 使う場面 |
|---|---|---|
DEBUG |
10 | 開発中の詳細な記録 |
INFO |
20 | 正常に進んだことの記録 |
WARNING |
30 | 問題の予兆(既定はここから) |
ERROR |
40 | 処理が失敗した |
CRITICAL |
50 | システムが続行できない |
logging.error()のまとめ
error()は処理が失敗したことを記録する。設定なしで出る- メッセージだけでは原因が分からない
- 例外処理では
logging.exception()でトレースバックを残す exc_info=Trueならどのレベルでも例外情報を付けられる- WARNINGとの境界は「目的を達成できたか」
- ログを出して握りつぶさない——
raiseで伝える - 追跡用のIDを入れ、機密情報は入れない


