PyCon JP 2025 Logo
広島国際会議場
JPEN
nikkie

nikkie

標準ライブラリのlogging、レゴブロックのように組合せてロギングできることを理解しよう!

ラン日本語
02:05 - 02:3530min
DAY 2
09/27
SAT

皆さんは標準ライブラリのloggingモジュールを使っていますか? 私は使っていますが、loggingモジュールは理解するのが難しかったですね。

どうやらこのモジュール、私にとってだけじゃなくPythonコミュニティにとっても難しそうなんですよね。 というのもChatGPT登場後に話題になったライブラリをいくつか触ったのですが、どれもロギングの実装が伸びしろ豊富でした。 実務で使うならロギングをしてアプリケーションの動きを手に取るように分かりたい、でもライブラリのロギングがオレオレすぎてライブラリユーザ側でハックが必要... いやーリアルワールドのロギングは大変苦労させられますね

こういった経験からPythonのロギングについては要点を押さえて伝えられるようになったと自負しているので、私のような苦労をする人が少しでも減るように、Pythonのロギングの基本の型を共有します。 ロギングは非機能な分、機能の実装に比べてかけられる時間も少なくなりがちだと思っています。 この発表と資料が、loggingモジュールに込められた組合せたロギングの1つの型を提供できたら嬉しいです(もちろん理解したうえで採用しないのもOKです)


トーク詳細 / Description

loggingモジュールにはいろいろな要素が含まれます。 ロガー、ハンドラ、フォーマッタ、フィルタ。 これらを組合せたロギングの型を1つ示します。

  • ライブラリ(importされるコード)でのロギングの実装:ロガー(+NullHandler)
  • アプリケーション(ライブラリをimportするコード)でのロギングの実装
    • ルートロガーにハンドラをつける
    • ハンドラにフォーマッタをつける
    • フィルタやログレベルをハンドラに設定できる

構成

(はじめにとまとめで3分)

loggingモジュールの構成要素(4分)

  • ロガー
  • ハンドラ
  • フォーマッタ
  • フィルタ

ロガーのレベルはどう決まる? ー NOTSET(5分)

  • ロガーのレベル以上の呼び出しでログレコードが作られる
  • ライブラリのコードでgetLogger()したとき、そのレベルは?
  • ロガーの階層構造
  • 親のロガーのレベルを変えると、子のロガーのレベルも変わる

ルートロガーでロギングしよう(8分)

  • ライブラリの作者は、ロギングのフォーマットや出力先には関心がない
  • propagate:子のロガーが作ったログレコードは親のロガーに渡る
  • ルートロガー(=一番親のロガー)にハンドラをつける
  • そのハンドラにフォーマッタをつける
  • 複数のハンドラを付ける例:「INFO以上はファイルにロギング、ERROR以上はコンソールにもログ出力」
  • 別のフォーマッタに差し替える例:JSONフォーマットでログ出力したい

伸びしろのあるロガーと、対処術(6分)

※メッセージとしては「こんなハックをする必要がないように、ロギングを実装してください」

  • printするものはロギングではありません(これは使わないという対処しかできない)
    • printとロギングの違い
    • やりたかったのだろう色付きロギング:フォーマッタへの差し替えを紹介
  • ライブラリでルートロガーを触ってはいけません
    • basicConfigの秘密:ルートロガーを触っています!
    • 巻き起こるpropagateによる2重出力
    • 解除方法(ルートロガーのハンドラをいじる)

落穂拾い(4分)

  • ライブラリのロガーにハンドラを付けない場合:「最終手段ハンドラ」でWARNING以上のメッセージを出力できる
  • コードを書く代わりにファイルでの設定
  • loguruなどeasyなライブラリの存在を紹介
nikkie

nikkie

プロフィール