Python|logging設計でロガー構造とレベル責任を整理する方法
この記事のポイント
- ロガー構造設計の崩壊パターンをレビュー視点で読み取れる
- レベル設計責任の分離整理を学べる
- 実務ログ設計の成長路線を体系化できる
- PlantUMLでロガー依存構造を可視化整理できる
そもそもloggingとは
Pythonの標準ライブラリ logging は、実行時の情報記録を行う柔軟なロギングシステムです。
- 階層化されたロガー設計(名前空間ベース)
- 出力レベル制御(DEBUG, INFO, WARNING, ERROR, CRITICAL)
- ハンドラー・フォーマッター分離
- ファイル出力、標準出力、外部転送等が可能
logging基本構成例
import logging
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
logger.info("Service started.")getLogger(__name__):モジュール毎のロガー生成setLevel():出力対象レベル設定info():実際のログ出力
なぜこれをレビューするのか
logging設計は「設計臭の蓄積領域」になりやすく、レビューアーの重点観察ポイントになります。
レビューアー視点
- ロガー構造(階層化)が整理されているか
- レベル設計(通知責任)が統制されているか
- ハンドラー構成が乱雑化していないか
- 初期化責任が集中統制されているか
- 実行時障害時のログ可読性が確保されているか
開発者視点
- 簡易print代替としてloggingを導入しがち
- getLogger()の乱立とsetLevel()の多発
- レベル設計を場当たりで書く習慣
- ハンドラー設定が分散しやすい
- 障害時のログ深度に後から困る
ロガー設計崩壊の典型設計臭
崩壊しやすいパターン
- ファイル内局所setLevel()多発
- モジュール単位でバラバラにgetLogger()
- ハンドラーが複数箇所で重複登録
- 全部INFO中心で実質レベル運用破綻
- ロガー命名が曖昧・統一ルール不在
崩壊例:局所レベル乱立型
局所乱立例
import logging
logger = logging.getLogger("service.user")
logger.setLevel(logging.DEBUG) # モジュール個別設定
def create_user():
logger.debug("create_user called.")
logger.info("user created successfully.")
@Reviewerモジュール局所でsetLevel()指定されています。中央初期化統制に統一してください。
問題点
- setLevel()が各所に分散
- 結果的に全体ログ粒度が統制不能化
崩壊構造モデル:ロガー乱立依存
良い設計整理アプローチ
logging設計は以下の整理原則で健全化できます。
① 中央初期化統制(Centralized Initialization)
logging_config.pyで統一管理- レベル・ハンドラー・フォーマッター集中管理
② 命名ルール統一(Hierarchical Namespace)
- パッケージ名ベース命名統一
__name__活用徹底
③ 責務別レベル設計(Responsibility-Driven Leveling)
| レベル | 責務用途 |
|---|---|
| DEBUG | 内部詳細検証 |
| INFO | 通常処理進行通知 |
| WARNING | 潜在リスク警告 |
| ERROR | 処理失敗通知 |
| CRITICAL | 即時障害通知 |
④ ハンドラー分離設計
- 標準出力、ファイル出力、障害通知先を責務分離
改善例:中央初期化統制版
logging_config.py
import logging
import sys
LOG_FORMAT = "%(asctime)s [%(levelname)s] %(name)s: %(message)s"
def init_logging():
root_logger = logging.getLogger()
root_logger.setLevel(logging.INFO)
formatter = logging.Formatter(LOG_FORMAT)
stream_handler = logging.StreamHandler(sys.stdout)
stream_handler.setFormatter(formatter)
root_logger.addHandler(stream_handler)- setLevel()はrootのみ
- 下位ロガーは継承統制
各モジュール側は統一
service/user.py
import logging
logger = logging.getLogger(__name__)
def create_user():
logger.info("user created successfully.")「ロガーは作る、粒度は中央で決める文化」
レビューアーは局所setLevel()消滅文化を推進するとログ健全性が飛躍します。
改善構造モデル:整理後依存統制
良くない実装例: ケース1(ハンドラー重複)
handler重複例
import logging
logger = logging.getLogger(__name__)
handler = logging.FileHandler("app.log")
logger.addHandler(handler)
@Reviewer各所で個別ハンドラー登録されています。中央初期化統制へ整理してください。
問題点
- 出力先管理が分散
- 重複ハンドリングで多重出力
良くない実装例: ケース2(レベル破綻)
レベル乱用例
import logging
logger = logging.getLogger(__name__)
def process_payment():
logger.info("connecting payment server")
logger.info("sending payment data")
logger.info("payment completed")
@Reviewer全てINFOで通知粒度が埋没しています。責務別レベル設計を適用してください。
問題点
- 情報粒度が揃いすぎて重要度差消失
- 障害時追跡性が劣化
改善例:責務別レベル整理
粒度適用版
def process_payment():
logger.debug("connecting payment server")
logger.info("sending payment data")
logger.info("payment completed")- DEBUG:接続開始など詳細系
- INFO:処理進行系
- WARNING/ERRORは例外系で使用
観点チェックリスト
まとめ
logging設計は「運用安定性の下支え」となる基盤領域です。
レビューアーは「中央統制文化・粒度統一文化・初期化集中文化」を継続指導することで、運用負荷の少ない健全ログ設計を確立できます。

