6.29 logging -- Python 用ロギング機能

バージョン 2.3 で 新たに追加 された仕様です。 このモジュールでは、アプリケーションのための柔軟なエラーログ記録 (logging) システムを実装するための関数やクラスを定義しています。

ログ記録は Logger クラスのインスタンス (以降 ロガー :logger) におけるメソッドを呼び出すことで行われます。各インスタンスは 名前をもち、ドット (ピリオド) を区切り文字として表記することで、 概念的には名前空間中の階層構造に配置されることになります。 例えば、"scan" と名づけられたロガーは "scan.text"、"scan.html"、 および "scan.pdf" ロガーの親ロガーとなります。ロガー名には何をつけてもよく、 ログに記録されるメッセージの生成元となるアプリケーション中の特定の 領域を示すことになります。

ログ記録されたメッセージにはまた、重要度レベル (level of importance) が関連付けられています。デフォルトのレベルとして提供されているものは DEBUGINFOWARNINGERROR および CRITICAL です。簡便性のために、 Logger の適切なメソッド群を呼ぶことで、ログに記録されたメッセージの 重要性を指定することができます。それらのメソッドとは、デフォルトの レベルを反映する形で、debug()info()warning()error() および critical() となっています。 これらのレベルを指定するにあたって制限はありません: Logger の より汎用的なメソッドで、明示的なレベル指定のための引数を持つ log() を使って自分自身でレベルを定義したり使用したりできます。

レベルもロガーに関連付けることができ、デベロッパが設定することも、 保存されたログ記録設定を読み込む際に設定することもできます。 ロガーに対してログ記録メソッドが呼び出されると、ロガーは自らの レベルとメソッド呼び出しに関連付けられたレベルを比較します。 ロガーのレベルがメソッド呼び出しのレベルよりも高い場合、実際の ログメッセージは生成されません。これはログ出力の冗長性を制御 するための基本的なメカニズムです。

ログ記録されるメッセージは LogRecord クラスのインスタンスとして コード化されます。ロガーがあるイベントを実際にログ出力すると決定した 場合、ログメッセージから LogRecord インスタンスが生成されます。

ログ記録されるメッセージは、ハンドラ (handlers) を通して、 処理機構 (dispatch mechanism) にかけられます。ハンドラは Handler クラスのサブクラスのインスタンスで、ログ記録された (LogRecord 形式の) メッセージが、そのメッセージの伝達対象となる相手 (エンドユーザ、サポートデスクのスタッフ、システム管理者、開発者) に行き着くようにする役割を持ちます。ハンドラには特定の行き先に方向付け られた LogRecord インスタンスが渡されます。各ロガーは ゼロ個、単一またはそれ以上のハンドラを (LoggeraddHandler() メソッド) で関連付けることができます。 ロガーに直接関連付けられたハンドラに加えて、 ロガーの上位にあるロガー全てに関連付けられたハンドラ がメッセージを処理する際に呼び出されます。

ロガーと同様に、ハンドラは関連付けられたレベルを持つことができます。 ハンドラのレベルはロガーのレベルと同じ方法で、フィルタとして働きます。 ハンドラがあるイベントを実際に処理すると決定した場合、 emit() メソッドが使われ、メッセージを発送先に送信します。ほとんどの ユーザ定義の Handler のサブクラスで、この emit() をオーバライドする必要があるでしょう。

基底クラスとなる Handler クラスに加えて、多くの有用なサブクラスが 提供されています:

  1. StreamHandler のインスタンスはストリーム (ファイル様 オブジェクト) にエラーメッセージを送信します。

  2. FileHandler のインスタンスはディスク上のファイルに エラーメッセージを送信します。

  3. BaseRotatingHandler はログファイルをある時点で交替させる ハンドラの基底クラスです。直接インスタンス化するためのクラスではありません。 RotatingFileHandlerTimeRotatingFileHandler を使う ようにしてください。

  4. RotatingFileHandler のインスタンスは最大ログファイルの サイズ指定とログファイルの交替機能をサポートしながら、ディスク上のファイルに エラーメッセージを送信します。

  5. TimeRotatingFileHandler のインスタンスは、ログファイルを 一定時間間隔ごとに交替しながら、ディスク上のファイルに エラーメッセージを送信します。

  6. SocketHandler のインスタンスは TCP/IP ソケットにエラーメッセージを送信します。

  7. DatagramHandler のインスタンスは UDP ソケットにエラーメッセージを送信します。

  8. SMTPHandler のインスタンスは指定された電子メールアドレスにエラーメッセージを送信します。

  9. SysLogHandler のインスタンスは遠隔を含むマシン上の syslog デーモンにエラーメッセージを送信します。

  10. NTEventLogHandler のインスタンスは Windows NT/2000/XP イベントログにエラーメッセージを送信します。

  11. MemoryHandler のインスタンスはメモリ上のバッファにエラーメッセージを送信し、指定された条件でフラッシュされるようにします。

  12. HTTPHandler のインスタンスは "GET" か "POST"セマンティクスを使って HTTP サーバにエラーメッセージを送信します。

StreamHandler および FileHandler クラスは、中核となる ログ化機構パッケージ内で定義されています。他のハンドラはサブモジュール、 logging.handlers で定義されています。 (サブモジュールには もうひとつ logging.config があり、これは環境設定機能の ためのものです。)

ログ記録されたメッセージは Formatter クラスのインスタンスを 介し、表示用に書式化されます。これらのインスタンスは % 演算子と辞書を 使うのに適した書式化文字列で初期化されます。

複数のメッセージの初期化をバッチ処理するために、 BufferingFormatter のインスタンスを使うことができます。 書式化文字列 (バッチ処理で各メッセージに適用されます) に加えて、 ヘッダ (header) およびトレイラ (trailer) 書式化文字列が用意されて います。

ロガーレベル、ハンドラレベルの両方または片方に基づいたフィルタリング が十分でない場合、Logger および Handler インスタンスに Filter のインスタンスを (addFilter() メソッドを介して) 追加することができます。メッセージの処理を進める前に、ロガーとハンドラは ともに、全てのフィルタでメッセージの処理が許可されているか調べます。 いずれかのフィルタが偽となる値を返した場合、メッセージの処理は 行われません。

基本的な Filter 機能では、指定されたロガー名でフィルタを 行えるようになっています。この機能が利用された場合、名前付けされた ロガーとその下位にあるロガーに送られたメッセージがフィルタを通過 できるようになり、その他のメッセージは捨てられます。

上で述べたクラスに加えて、いくつかのモジュールレベルの関数が存在します。

getLogger( [name])
指定された名前のロガーを返します。名前が指定されていない場合、 ロガー階層のルート (root) にあるロガーを返します。 name を指定する場合には、通常は "a", "a.b", あるいは "a.b.c.d" といったようなドット区切りの階層的な 名前にします。名前の付け方はログ機能を使う開発者次第です。

与えられた名前に対して、この関数はどの呼び出しでも同じロガーインスタンス を返します。従って、ロガーインスタンスをアプリケーションの各部 でやりとりする必要はなくなります。

getLoggerClass( )
標準のLogger クラスか、最後にsetLoggerClass() に渡した クラスを返します。この関数は、新たに定義するクラス内で呼び出し、 カスタマイズしたLogger クラスのインストールを行うときに 既に他のコードで適用したカスタマイズを取り消そうとしていないか 確かめるのに使います。例えば以下のようにします:

 class MyLogger(logging.getLoggerClass()):
     # ... override behaviour here

debug( msg[, *args[, **kwargs]])
レベル DEBUG のメッセージをルートロガーで記録します。 msg はメッセージの書式化文字列で、argsmsg に 取り込むための引数です。キーワード文字列 kwargs からは exc_info のみが調べられ、この値の評価値が偽でない場合、 例外情報をログメッセージに追加します。(sys.exc_info の返す形式の) 例外情報を表すタプルが与えられていれば、それを メッセージに使います。それ以外の場合には、sys.exc_info を呼び出して例外情報を取得します。

info( msg[, *args[, **kwargs]])
レベル INFO のメッセージをルートロガーで記録します。 引数は debug() と同じように解釈されます。

warning( msg[, *args[, **kwargs]])
レベル WARNING のメッセージをルートロガーで記録します。 引数は debug() と同じように解釈されます。

error( msg[, *args[, **kwargs]])
レベル ERROR のメッセージをルートロガーで記録します。 引数は debug() と同じように解釈されます。

critical( msg[, *args[, **kwargs]])
レベル CRITICAL のメッセージをルートロガーで記録します。 引数は debug() と同じように解釈されます。

exception( msg[, *args])
レベル ERROR のメッセージをルートロガーで記録します。 引数は debug() と同じように解釈されます。 例外情報はログメッセージに追加されます。このメソッドは 例外ハンドラからのみ呼び出されます。

log( level, msg[, *args[, **kwargs]])
レベル level のメッセージをルートロガーで記録します。 その他の引数は debug() と同じように解釈されます。

disable( lvl)
全てのロガーに対して、ロガー自体のレベルに優先するような上書きレベル lvl を与えます。アプリケーション全体にわたって一時的にログ出力の 頻度を押し下げる必要が生じた場合にはこの関数が有効です。

addLevelName( lvl, levelName)
内部辞書内でレベル lvl をテキスト levelName に関連付け ます。これは例えば Formatter でメッセージを書式化する 際のように、数字のレベルをテキスト表現に対応付ける際に用いられます。 この関数は自作のレベルを定義するために使うこともできます。 使われるレベル対する唯一の制限は、レベルは正の整数でなくては ならず、メッセージの深刻さが上がるに従ってレベルの数も上がらなくては ならないということです。

getLevelName( lvl)
ログ記録レベル lvl のテキスト表現を返します。レベルが定義 済みのレベル CRITICALERRORWARNINGINFO、あるいは DEBUG のいずれかである場合、対応する文字列が返されます。 addLevelName() を使ってレベルに名前を関連づけていた 場合、lvl に関連付けられていた名前が返されます。 定義済みのレベルに対応する数値を指定した場合、レベルに対応した 文字列表現を返します。そうでない場合、文字列 "Level %s" % lvl を 返します。

makeLogRecord( attrdict)
属性が attrdict で定義された、新たな LogRecord インスタンスを生成して返します。この関数は pickle 化された LogRecord 属性の辞書を作成し、ソケットを介して送信し、受信端で LogRecord インスタンスとして再構成する際に便利です。

makeLogRecord( attrdict)
attrdict で属性を定義した、新しい LogRecord インスタンスを 返します。この関数は、逆 pickle 化された LogRecord 属性辞書を socket 越しに受け取り、受信端で LogRecord インスタンスに再構築す る場合に有用です。

basicConfig( )
デフォルトのフォーマッタ (formatter) を持つ StreamHandler を生成してルートロガーに追加し、ログ記録システムの基本的な環境設定を 行います。 関数 debug()info()warning()error()、および critical() は、ルートロガーに ハンドラが定義されていない場合に自動的に basicConfig() を呼び出します。

shutdown( )
ログ記録システムに対して、バッファのフラッシュを行い、全てのハンドラを 閉じることで順次シャットダウンを行うように告知します。

setLoggerClass( klass)
ログ記録システムに対して、ロガーをインスタンス化する際にクラス klass を使うように指示します。指定するクラスは引数として 名前だけをとるようなメソッド __init__() を定義して いなければならず、__init__() では Logger.__init__() を呼び出さなければなりません。典型的な利用法として、この関数は自作の ロガーを必要とするようなアプリケーションにおいて、他のロガーが インスタンス化される前にインスタンス化されます。

参考:

PEP 282, A Logging System
本機能を Python 標準ライブラリに含めるよう記述している提案書。
この logging パッケージのオリジナル
オリジナルのloggingパッケージ。このサイトにあるバー ジョンのパッケージは、標準でloggingパッケージを含まな いPython 1.5.2 と 2.1.x、2.2.xでも使用できます



ご意見やご指摘をお寄せになりたい方は、 このドキュメントについて... をご覧ください。