nikkie

nikkie

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

ダリア2#pyconjp_3中級日本語
11:05 - 11: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なライブラリの存在を紹介

この題材を選んだ理由やきっかけ

RevChatGPT、crawl4ai、browser-useという近年話題になったライブラリをロギングしようとして、それぞれかなりやんちゃな実装をしているために苦労しました(同時にloggingへの理解は非常に深まりました)。 これはもう多数のPython使いにとってloggingが難しいんだなと思い至り、ライブラリのユーザに苦労を強いることのないロギング(loggingの思想に沿ったロギング実装)をコミュニティに伝えるべく、発表提案を送りました


オーディエンスが持って帰れる具体的な知識やノウハウ

  • loggingモジュールの思想(シンプル=組合せられる)の理解
    • ロガー、ハンドラ、フォーマッタなどの構成要素の理解含む
  • 「ルートロガーにpropagateしてロギングする」という一つの型を持ち帰れます
  • 「INFO以上はファイルにロギング、ERROR以上はコンソールにもログ出力」をloggingモジュールで実装するやり方

オーディエンスに求める前提知識

Pythonでロギングを実装した経験は前提とします。loggingモジュールは使っていなくてもよいです。

Pythonのロギングに自信がない方や「INFO以上はファイルにロギング、ERROR以上はコンソールにもログ出力」がloggingだと自力で実装できないなという方は、ぜひ聞きに来てください。持ち帰れるものが多いと思います

  • loggingモジュールいまいちわからないなと感じつつロギングを実装している方
    • 他の人にimportしてもらうコードにあなたがlogging.info()logging.basicConfig()を書いているなら、この話を聞くのをオススメします
  • ふだんloggingモジュールは使わずにより簡単なサードパーティライブラリでロギングを実装している方
nikkie

nikkie

プロフィール

株式会社ユーザベースの機械学習エンジニア。Pythonを書いて最近はLLMと戯れている。 Pythonで作った小さなソフトウェアをいくつか公開している。代表作:https://github.com/ftnext/sphinx-new-tab-link ブログを技術記事を中心に毎日書いて1000日経過 https://nikkie-ftnext.hatenablog.com/ https://x.com/ftnext 毎月のみんなのPython勉強会スタッフ。PyCon JP 2021座長