🐥

【Python】Loggingを理解する

に公開

logging とは

  • Pythonの標準ライブラリモジュールとして利用可能なログ記録API。

基本的なオブジェクトとロギングレベル

  • オブジェクト
オブジェクト名 説明
ロガー アプリケーションコードが直接使うインターフェースを公開します。
ハンドラ (ロガーによって生成された) ログ記録を適切な送信先に送ります。
フォーマッタ ログ記録が最終的に出力されるレイアウトを指定します。
フィルタ どのログ記録を出力するかを決定する、きめ細かい機能を提供します。
  • ロギングレベル
    • ログレベル(厳密にはログレベルの数値)を定義したもの。
レベル 意味
logging.NOTSET ・実際のログレベルは祖先のロガーを参照して決めることを意味します。
・実効ログレベル、またはハンドラーに対してこのレベルが設定された場合、全てのイベントが処理されます。
logging.DEBUG ・詳細情報。(問題が発生した際に原因を突き止めようとする開発者向けの情報。)
logging.INFO ・想定された通りのことが起こったことの確認。
logging.WARNING ・想定外の事象、または近い将来に問題が起きる可能性の表示。
・ソフトウエアは引き続き期待通りに動作している状態。
logging.ERROR ・より重大な問題により、ソフトウェアがある機能を実行できないこと。
logging.CRITICAL ・プログラム自体が実行を続けられないことを表す、重大なエラー。

ロガーオブジェクト

  • logging モジュールにおけるルートオブジェクト。
    • getLogger() によってロガーオブジェクトを参照する。
    • 使用の際は、Pythonモジュール単位での構築が推奨される。
      • logging.getLogger(__name__)
    • ルートロガーの直接のインスタンス化はNG(ダメ、絶対)

ハンドラオブジェクト

  • サブクラスの基底クラス。

フォーマッタオブジェクト

  • 実際に出力されるログメッセージのフォーマットを定義する。
パラメータ 説明
fmt style で指定された書式にもとづく、出力ログ全体に対する書式文字列。
datefmt style で指定された書式にもとづく、出力ログの日時を示す部分に対する書式文字列。
style '%', または '$' のいずれかで、書式文字列がログデータとどのようにマージされるかを決める。

フィルタオブジェクト

  • ログレベルよりもさらに細かいログ制御を実現。
    • 同レベルの中でさらにフィルタリングしたい場合に使用する。


logging.handlers とは

  • ハンドラオブジェクトを定義する。
  • StreamHandler
    • ログ出力をターミナル(ストリーム)へ送信する。
  • FileHandler
    • ログ出力をディスク上のファイルに送信する。


logging.config とは

  • logging モジュールの環境設定を行うためのAPI。
    • logging または logging.handlers で宣言されているハンドラを定義することで設定する。
  • logging.config.dictConfig()


チートシート

  • 環境設定(.yml)
version: 1
formatters:
  simple:
    format: '%(asctime)s - %(levelname)s - %(message)s'
    datefmt: '%Y-%m-%d %H:%M:%S'
  detail:
    format: '%(asctime)s - %(levelname)s - %(filename)s:%(lineno)d %(funcName)s - %(message)s'
    datefmt: '%Y-%m-%d %H:%M:%S'
handlers:
  console:
    class: logging.StreamHandler
    formatter: simple
    stream: ext://sys.stdout
  file:
    class: logging.FileHandler
    formatter: detail
    filename: logging.log
loggers:
  consoler:
    level: INFO
    handlers: [console]
    propagate: no
  filer:
    level: INFO
    handlers: [file]
    propagate: no
root:
  level: NOTSET
  handlers: [console]
  • 呼び出し(.py)
import yaml
import logging

with open('env/logging.yml', 'r') as file:
    _logging = yaml.safe_load(file.read())

# loggingモジュールの構築
logging.config.dictConfig(_logging)

# logger.handlerのインスタンス化
filer: logging.Logger = logging.getLogger("filer")

# ログの出力
filer.debug("これはdebugレベルのログです")


# logger.handlerのクローズ
[handler.close() for handler in filer.handlers]

Discussion