15.7. logging
— Python 用ロギング機能¶
Source code: Lib/logging/__init__.py
バージョン 2.3 で追加.
このモジュールは、アプリケーションやライブラリのための柔軟なエラーログ記録 (logging) システムを実装するための関数やクラスを定義しています。
標準ライブラリモジュールとしてログ記録 API が提供される利点は、すべての Python モジュールがログ記録に参加できることであり、これによってあなたが書くアプリケーションのログにサードパーティーのモジュールが出力するメッセージを含ませることができます。
このモジュールは、多くの機能性と柔軟性を提供します。ロギングに慣れていないなら、つかむのに一番いいのはチュートリアルを読むことです (右のリンクを参照してください)。
モジュールで定義されている基本的なクラスと関数を、以下に列挙します。
- ロガーは、アプリケーションコードが直接使うインタフェースを公開します。
- ハンドラは、(ロガーによって生成された) ログ記録を適切な送信先に送ります。
- フィルタは、どのログ記録を出力するかを決定する、きめ細かい機能を提供します。
- フォーマッタは、ログ記録が最終的に出力されるレイアウトを指定します。
15.7.1. ロガーオブジェクト¶
ロガーには以下のような属性とメソッドがあります。ロガーを直接インスタンス化することはできず、常にモジュール関数 logging.getLogger(name)
を介してインスタンス化することに注意してください。同じ name で getLogger()
を複数回呼び出すと、常に同じロガー・オブジェクトへの参照が返されます。
name
は foo.bar.baz
のようにピリオドで分割された (ただし単なるプレーンな foo
もありえます) 潜在的に階層的な値です。階層リスト中でより下位のロガーは、上位のロガーの子です。例えば、foo
という名前を持つロガーがあるとき、foo.bar
, foo.bar.baz
, foo.bam
という名前を持つロガーはすべて foo
の子孫です。ロガー名の階層は Python パッケージ階層と類似していて、推奨される構築方法 logging.getLogger(__name__)
を使用してロガーをモジュール単位で構成すれば、Python パッケージ階層と同一になります。これは、モジュールの中では __name__
が Python パッケージ名前空間におけるモジュール名だからです。
-
class
logging.
Logger
¶
-
Logger.
propagate
¶ これが真と評価されると、記録されたイベントがこのロガーに向けられるとそれはこのロガーに所属する全てのハンドラに渡されるとともに、上位 (祖先) ロガーのハンドラにも渡されます。メッセージは、祖先ロガーのハンドラに直接渡されます - 今問題にしている祖先ロガーのレベルもフィルタも、どちらも考慮されません。
この値の評価結果が偽になる場合、ロギングメッセージは祖先ロガーのハンドラに渡されません。
コンストラクタはこの属性を
True
に設定します。注釈
一つのロガー と 一つ以上のその祖先にハンドラを接続すると、同一レコードが何度も発行されます。一般的に言って、ハンドラを複数のロガーに接続しようと考えるべきではありません - ロガーの階層においての最上位のロガーがそれを接続するのに相応しく、そうすれば propagate 設定を
True
にすることで、全ての子孫ロガーが記録する全てのイベントをそのハンドラが参照することが出来ます。一般的なシナリオは、ハンドラはルートロガーに対してのみ接続し、残りのものについての propagate 設定を注意深く行います。
-
Logger.
setLevel
(level)¶ Sets the threshold for this logger to level. Logging messages which are less severe than level will be ignored. When a logger is created, the level is set to
NOTSET
(which causes all messages to be processed when the logger is the root logger, or delegation to the parent when the logger is a non-root logger). Note that the root logger is created with levelWARNING
.「親ロガーに委譲」という用語の意味は、もしロガーのレベルが NOTEST ならば、祖先ロガーの系列の中を NOTEST 以外のレベルの祖先を見つけるかルートに到達するまで辿っていく、ということです。
もし NOTEST 以外のレベルの祖先が見つかったなら、その祖先のレベルが探索を開始したロガーの実効レベルとして扱われ、ログイベントがどのように処理されるかを決めるのに使われます。
ルートに到達した場合、ルートのレベルが NOTEST ならばすべてのメッセージは処理されます。そうでなければルートのレベルが実効レベルとして使われます。
レベルの一覧については ロギングレベル を参照してください。
-
Logger.
isEnabledFor
(lvl)¶ 深刻度が lvl のメッセージが、このロガーで処理されることになっているかどうかを示します。このメソッドはまず、
logging.disable(lvl)
で設定されるモジュールレベルの深刻度レベルを調べ、次にロガーの実効レベルをgetEffectiveLevel()
で調べます。
-
Logger.
getEffectiveLevel
()¶ このロガーの実効レベルを示します。
NOTSET
以外の値がsetLevel()
で設定されていた場合、その値が返されます。そうでない場合、NOTSET
以外の値が見つかるまでロガーの階層をルートロガーの方向に追跡します。見つかった場合、その値が返されます。返される値は整数で、典型的にはlogging.DEBUG
,logging.INFO
等のうち一つです。
-
Logger.
getChild
(suffix)¶ このロガーの子であるロガーを、接頭辞によって決定し、返します。従って、
logging.getLogger('abc').getChild('def.ghi')
は、logging.getLogger('abc.def.ghi')
によって返されるのと同じロガーを返すことになります。これは簡便なメソッドで、親ロガーがリテラルでなく__name__
などを使って名付けられているときに便利です。バージョン 2.7 で追加.
-
Logger.
debug
(msg, *args, **kwargs)¶ レベル
DEBUG
のメッセージをこのロガーで記録します。 msg はメッセージの書式化文字列で、 args は msg に文字列書式化演算子を使って取り込むための引数です。 (これは、書式化文字列の中でキーワードを使い、引数として単一の辞書を渡すことができる、ということを意味します。)キーワード引数 kwargs からは 2 つのキーワードが調べられます。一つ目は exc_info で、この値の評価値が false でない場合、例外情報をログメッセージに追加します。 (
sys.exc_info()
の返す形式の) 例外情報を表すタプルが与えられていれば、それをメッセージに使います。それ以外の場合には、sys.exc_info()
を呼び出して例外情報を取得します。2番目のキーワード引数は extra で、当該ログイベント用に作られる LogRecoed の __dict__ にユーザー定義属性を加えるのに使われる辞書を渡すために用いられます。これらの属性は好きなように使えます。たとえば、ログメッセージの一部にすることもできます。以下の例を見てください:
FORMAT = '%(asctime)-15s %(clientip)s %(user)-8s %(message)s' logging.basicConfig(format=FORMAT) d = {'clientip': '192.168.0.1', 'user': 'fbloggs'} logger = logging.getLogger('tcpserver') logger.warning('Protocol problem: %s', 'connection reset', extra=d)
出力はこのようになります
2006-02-08 22:20:02,165 192.168.0.1 fbloggs Protocol problem: connection reset
extra で渡される辞書のキーはロギングシステムで使われているものと衝突しないようにしなければなりません。 (どのキーがロギングシステムで使われているかについての詳細は
Formatter
のドキュメントを参照してください。)これらの属性をログメッセージに使うことにしたなら、少し注意が必要です。上の例では、 'clientip' と 'user' が LogRecord の属性辞書に含まれていることを期待した書式化文字列で
Formatter
がセットアップされています。もしこれらが欠けていると、書式化例外が発生してしまうためメッセージはログに残りません。したがってこの場合、常にこれらのキーを含む extra 辞書を渡す必要があります。このようなことは煩わしいかもしれませんが、この機能は限定された場面で使われるように意図しているものなのです。たとえば同じコードがいくつものコンテキストで実行されるマルチスレッドのサーバで、興味のある条件が現れるのがそのコンテキストに依存している (上の例で言えば、リモートのクライアント IP アドレスや認証されたユーザ名など)、というような場合です。そういった場面では、それ用の
Formatter
が特定のHandler
と共に使われるというのはよくあることです。
-
Logger.
log
(lvl, msg, *args, **kwargs)¶ 整数で表したレベル lvl のメッセージをこのロガーで記録します。その他の引数は
debug()
と同じように解釈されます。
-
Logger.
exception
(msg, *args, **kwargs)¶ レベル
ERROR
のメッセージをこのロガーで記録します。引数は、渡された exc_info の詳細が展開されないことを除いて、debug()
と同じように解釈されます。例外情報が常にログメッセージに追加されます。このメソッドは例外ハンドラからのみ呼び出されるべきです。
-
Logger.
addFilter
(filter)¶ Adds the specified filter filter to this logger.
-
Logger.
removeFilter
(filter)¶ Removes the specified filter filter from this logger.
-
Logger.
filter
(record)¶ レコードに対してこのロガーのフィルタを適用し、レコードが処理されるべき場合に真を返します。フィルタのいずれかの値が偽を返すまで、それらは順番に試されていきます。いずれも偽を返さなければ、レコードは処理される(ハンドラに渡される)ことになります。ひとつでも偽を返せば、発生したレコードはもはや処理されることはありません。
-
Logger.
addHandler
(hdlr)¶ 指定されたハンドラ hdlr をこのロガーに追加します。
-
Logger.
removeHandler
(hdlr)¶ 指定されたハンドラ hdlr をこのロガーから取り除きます。
-
Logger.
findCaller
()¶ 呼び出し元のソースファイル名と行番号を調べます。ファイル名と行番号、関数名を 3 要素のタプルで返します。
バージョン 2.4 で変更: 関数名が追加されました。以前のバージョンでは、ファイル名と行番号の、2 要素のタプルを返していました。
15.7.2. ロギングレベル¶
ログレベルの数値は以下の表のように与えられています。これらは基本的に自分でレベルを定義したい人のためのもので、定義するレベルを既存のレベルの間に位置づけるためには具体的な値が必要になります。もし数値が他のレベルと同じだったら、既存の値は上書きされその名前は失われます。
レベル | Numeric value |
---|---|
CRITICAL |
50 |
ERROR |
40 |
WARNING |
30 |
INFO |
20 |
DEBUG |
10 |
NOTSET |
0 |
15.7.3. ハンドラオブジェクト¶
ハンドラ (Handler) は以下の属性とメソッドを持ちます。 Handler
は直接インスタンス化されることはありません; このクラスはより便利なサブクラスの基底クラスとして働きます。しかしながら、サブクラスにおける __init__()
メソッドでは、 Handler.__init__()
を呼び出す必要があります。
-
Handler.
__init__
(level=NOTSET)¶ レベルを設定して、
Handler
インスタンスを初期化します。空のリストを使ってフィルタを設定し、 I/O 機構へのアクセスを直列化するために (createLock()
を使って) ロックを生成します。
-
Handler.
createLock
()¶ スレッドセーフでない背後の I/O 機能に対するアクセスを直列化するために用いられるスレッドロック (thread lock) を初期化します。
-
Handler.
acquire
()¶ createLock()
で生成されたスレッドロックを獲得します。
-
Handler.
setLevel
(level)¶ Sets the threshold for this handler to level. Logging messages which are less severe than level will be ignored. When a handler is created, the level is set to
NOTSET
(which causes all messages to be processed).レベルの一覧については ロギングレベル を参照してください。
-
Handler.
addFilter
(filter)¶ Adds the specified filter filter to this handler.
-
Handler.
removeFilter
(filter)¶ Removes the specified filter filter from this handler.
-
Handler.
filter
(record)¶ レコードに対してこのハンドラのフィルタを適用し、レコードが処理されるべき場合に真を返します。フィルタのいずれかの値が偽を返すまで、それらは順番に試されていきます。いずれも偽を返さなければ、レコードは発行されることになります。ひとつでも偽を返せば、ハンドラはレコードを発行しません。
-
Handler.
flush
()¶ すべてのログ出力がフラッシュされるようにします。このクラスのバージョンではなにも行わず、サブクラスで実装するためのものです。
-
Handler.
close
()¶ ハンドラで使われているすべてのリソースの後始末を行います。このバージョンでは何も出力せず、
shutdown()
が呼ばれたときに閉じられたハンドラを内部リストから削除します。サブクラスではオーバライドされたclose()
メソッドからこのメソッドが必ず呼ばれるようにしてください。
-
Handler.
handle
(record)¶ ハンドラに追加されたフィルタの条件に応じて、指定されたログレコードを出力します。このメソッドは I/O スレッドロックの獲得/解放を伴う実際のログ出力をラップします。
-
Handler.
handleError
(record)¶ このメソッドは
emit()
の呼び出し中に例外に遭遇した際にハンドラから呼び出されます。モジュールレベル属性raiseExceptions
がFalse
の場合、例外は暗黙のまま無視されます。ほとんどの場合、これがロギングシステムの望ましい動作です - というのは、ほとんどのユーザはロギングシステム自体のエラーは気にせず、むしろアプリケーションのエラーに興味があるからです。しかしながら、望むならこのメソッドを自作のハンドラと置き換えることもできます。 record には、例外発生時に処理されていたレコードが入ります。 (raiseExceptions のデフォルト値はTrue
です。これは開発中はその方が便利だからです)。
-
Handler.
format
(record)¶ レコードに対する書式化を行います - フォーマッタが設定されていれば、それを使います。そうでない場合、モジュールにデフォルト指定されたフォーマッタを使います。
-
Handler.
emit
(record)¶ 指定されたログ記録レコードを実際にログ記録する際のすべての処理を行います。このメソッドはサブクラスで実装されることを意図しており、そのためこのクラスのバージョンは
NotImplementedError
を送出します。
標準として含まれているハンドラについては、 logging.handlers
を参照してください。
15.7.4. フォーマッタオブジェクト¶
フォーマッタ (Formatter
) は以下の属性とメソッドを持っています。 Formatter
は LogRecord
を (通常は) 人間か外部のシステムで解釈できる文字列に変換する役割を担っています。基底クラスの Formatter
では書式化文字列を指定することができます。何も指定されなかった場合、ロギングコール中のメッセージ以外の情報だけを持つ '%(message)s'
の値が使われます。フォーマットされた出力に情報の要素 (タイムスタンプなど) を追加したいなら、このまま読み進めてください。
Formatter は LogRecord
属性の知識を利用できるような書式化文字列を用いて初期化することができます。例えば、上で言及したデフォルト値では、ユーザによるメッセージと引数はあらかじめ書式化されて、 LogRecord
の message 属性に入っていることを利用しています。この書式化文字列は、 Python 標準の % を使った変換文字列で構成されます。文字列整形に関する詳細は 文字列フォーマット操作 を参照してください。
LogRecord
の便利なマッピングキーは、 LogRecord 属性 の節で与えられます。
-
class
logging.
Formatter
(fmt=None, datefmt=None)¶ Formatter
クラスの新たなインスタンスを返します。インスタンスは全体としてのメッセージに対する書式化文字列と、メッセージの日付/時刻部分のための書式化文字列を伴って初期化されます。 fmt が指定されない場合、'%(message)s'
が使われます。 datefmt が指定されない場合、 ISO8601 日付書式が使われます。-
format
(record)¶ レコードの属性辞書が、文字列を書式化する演算で被演算子として使われます。書式化された結果の文字列を返します。辞書を書式化する前に、二つの準備段階を経ます。レコードの message 属性が msg % args を使って処理されます。書式化された文字列が
'(asctime)'
を含むなら、formatTime()
が呼び出され、イベントの発生時刻を書式化します。例外情報が存在する場合、formatException()
を使って書式化され、メッセージに追加されます。ここで注意していただきたいのは、書式化された例外情報は exc_text にキャッシュされるという点です。これが有用なのは例外情報がピックル化されて回線上を送ることができるからですが、しかし二つ以上のFormatter
サブクラスで例外情報の書式化をカスタマイズしている場合には注意が必要になります。この場合、フォーマッタが書式化を終えるごとにキャッシュをクリアして、次のフォーマッタがキャッシュされた値を使わずに新鮮な状態で再計算するようにしなければならないことになります。
-
formatTime
(record, datefmt=None)¶ このメソッドは、フォーマッタが書式化された時間を利用したい際に、
format()
から呼び出されます。このメソッドは特定の要求を提供するためにフォーマッタで上書きすることができますが、基本的な振る舞いは以下のようになります: datefmt (文字列) が指定された場合、レコードが生成された時刻を書式化するためにtime.strftime()
で使われます。そうでない場合、 ISO8601 書式が使われます。結果の文字列が返されます。この関数は、ユーザが設定できる関数を使って、生成時刻をタプルに変換します。デフォルトでは、
time.localtime()
が使われます。特定のフォーマッタインスタンスに対してこれを変更するには、converter
属性をtime.localtime()
やtime.gmtime()
と同じ署名をもつ関数に設定してください。すべてのフォーマッタインスタンスに対してこれを変更するには、例えば全てのロギング時刻を GMT で表示するには、Formatter
クラスのconverter
属性を設定してください。
-
formatException
(exc_info)¶ 指定された例外情報 (
sys.exc_info()
が返すような標準例外のタプル) を文字列として書式化します。デフォルトの実装は単にtraceback.print_exception()
を使います。結果の文字列が返されます。
-
15.7.5. フィルタオブジェクト¶
フィルタ (Filter)
は、ハンドラ
や ロガー
によって使われ、レベルによって提供されるのよりも洗練されたフィルタリングを実現します。基底のフィルタクラスは、ロガー階層構造内の特定地点の配下にあるイベントだけを許可します。例えば、'A.B' で初期化されたフィルタは、ロガー 'A.B', 'A.B.C', 'A.B.C.D', 'A.B.D' 等によって記録されたイベントは許可しますが、'A.BB', 'B.A.B' などは許可しません。空の文字列で初期化された場合、すべてのイベントを通過させます。
-
class
logging.
Filter
(name='')¶ Filter
クラスのインスタンスを返します。 name が指定されていれば、 name はロガーの名前を表します。指定されたロガーとその子ロガーのイベントがフィルタを通過できるようになります。 name が指定されなければ、すべてのイベントを通過させます。-
filter
(record)¶ 指定されたレコードがログされるべきか?no ならばばゼロを、yes ならばゼロでない値を返します。適切と判断されれば、このメソッドによってレコードはその場で修正されることがあります。
-
ハンドラに対するフィルタはハンドラがイベントを発行する前に試され、一方ではロガーに対するフィルタは、イベントが(debug()
, info()
などによって)ロギングされる際には、ハンドラにイベントが送信される前にはいつでも試されることに注意してください。そのフィルタがそれら子孫ロガーにも適用されていない限り、子孫ロガーによって生成されたイベントはロガーのフィルタ設定によってフィルタされることはありません。
実際には、Filter
をサブクラス化する必要はありません。同じ意味の filter
メソッドを持つ、すべてのインスタンスを通せます。
フィルタは本来、レコードをレベルよりも洗練された基準に基づいてフィルタするために使われますが、それが取り付けられたハンドラやロガーによって処理されるレコードをすべて監視します。これは、特定のロガーやハンドラに処理されたレコードの数を数えたり、処理されている LogRecord の属性を追加、変更、削除したりするときに便利です。もちろん、LogRecord を変更するには注意が必要ですが、これにより、ログにコンテキスト情報を注入できます (Filter を使ったコンテキスト情報の伝達 を参照してください)。
15.7.6. LogRecord オブジェクト¶
LogRecord
インスタンスは、何かをログ記録するたびに Logger
によって生成されます。また、 makeLogRecord()
を通して (例えば、ワイヤを通して受け取られた pickle 化されたイベントから) 手動で生成することも出来ます。
-
class
logging.
LogRecord
(name, level, pathname, lineno, msg, args, exc_info, func=None)¶ ロギングされているイベントに適切なすべての情報を含みます。
基本的な情報は
msg
とargs
に渡され、レコードのmessage
フィールドはmsg % args
による結合で生成されます。パラメータ: - name – この LogRecord で表されるイベントをロギングするのに使われるロガーの名前です。ここで与える名前が、たとえ他の(祖先の)ロガーに結び付けられたハンドラによって発せられるとしても、与えたこの値のままであることに注意してください。
- level – このロギングイベントの数値のレベル (DEBUG, INFO などのいずれか) です。なお、これは LogRecord の 2つの 属性に変換されます。数値
levelno
と、対応するレベル名levelname
です。 - pathname – ロギングの呼び出しが発せられたファイルの完全なパス名。
- lineno – ロギングの呼び出しが発せられたソース行番号。
- msg – イベント記述メッセージで、これは変数データのプレースホルダを持つフォーマット文字列になり得ます。
- args – msg 引数と組み合わせてイベント記述を得るための変数データです。
- exc_info – 現在の例外情報を含む例外タプルか、利用できる例外情報がない場合は
None
です。 - func – ロギングの呼び出しを行った関数またはメソッドの名前です。
バージョン 2.5 で変更: func が追加されました。
15.7.7. LogRecord 属性¶
LogRecord には幾つかの属性があり、そのほとんどはコンストラクタのパラメタから得られます。(なお、LogRecord コンストラクタのパラメタと LogRecord 属性が常に厳密に対応するわけではありません。) これらの属性は、レコードからのデータをフォーマット文字列に統合するのに使えます。以下のテーブルに、属性名、意味、そして % 形式フォーマット文字列における対応するプレースホルダを (アルファベット順に) 列挙します。
属性名 | フォーマット | 説明 |
---|---|---|
args | このフォーマットを自分で使う必要はないでしょう。 | msg に組み合わせて message を生成するための引数のタプル、または、マージに用いられる辞書(引数が一つしかなく、かつそれが辞書の場合)。 |
asctime | %(asctime)s |
LogRecord が生成された時刻を人間が読める書式で表したもの。デフォルトでは "2003-07-08 16:49:45,896" 形式 (コンマ以降の数字は時刻のミリ秒部分) です。 |
created | %(created)f |
LogRecord が生成された時刻 (time.time() によって返される形式で)。 |
exc_info | このフォーマットを自分で使う必要はないでしょう。 | (sys.exc_info 風の) 例外タプルか、例外が起こっていない場合は None 。 |
filename | %(filename)s |
pathname のファイル名部分。 |
funcName | %(funcName)s |
ロギングの呼び出しを含む関数の名前。 |
levelname | %(levelname)s |
メッセージのための文字のロギングレベル ('DEBUG' , 'INFO' , 'WARNING' , 'ERROR' , 'CRITICAL' )。 |
levelno | %(levelno)s |
メッセージのための数値のロギングレベル (DEBUG , INFO , WARNING , ERROR , CRITICAL )。 |
lineno | %(lineno)d |
ロギングの呼び出しが発せられたソース行番号 (利用できる場合のみ)。 |
モジュール | %(module)s |
モジュール (filename の名前部分)。 |
msecs | %(msecs)d |
LogRecord が生成された時刻のミリ秒部分。 |
message | %(message)s |
msg % args として求められた、ログメッセージ。 Formatter.format() が呼び出されたときに設定されます。 |
msg | このフォーマットを自分で使う必要はないでしょう。 | 元のロギングの呼び出しで渡されたフォーマット文字列。 args と合わせて、 message 、または任意のオブジェクトを生成します (任意のオブジェクトをメッセージに使用する 参照)。 |
name | %(name)s |
ロギングに使われたロガーの名前。 |
pathname | %(pathname)s |
ロギングの呼び出しが発せられたファイルの完全なパス名 (利用できる場合のみ)。 |
プロセス | %(process)d |
プロセス ID (利用可能な場合のみ)。 |
processName | %(processName)s |
プロセス名 (利用可能な場合のみ)。 |
relativeCreated | %(relativeCreated)d |
logging モジュールが読み込まれた時刻に対する、LogRecord が生成された時刻を、ミリ秒で表したもの。 |
thread | %(thread)d |
スレッド ID (利用可能な場合のみ)。 |
threadName | %(threadName)s |
スレッド名 (利用可能な場合のみ)。 |
バージョン 2.5 で変更: funcName が追加されました。
バージョン 2.6 で変更: processName が追加されました。
15.7.8. LoggerAdapter オブジェクト¶
LoggerAdapter
インスタンスは文脈情報をログ記録呼び出しに渡すのを簡単にするために使われます。使い方の例は コンテキスト情報をログ記録出力に付加する を参照してください。
バージョン 2.6 で追加.
-
class
logging.
LoggerAdapter
(logger, extra)¶ 内部で使う
Logger
インスタンスと辞書風 (dict-like) オブジェクトで初期化したLoggerAdapter
のインスタンスを返します。-
process
(msg, kwargs)¶ 文脈情報を挿入するために、ログ記録呼び出しに渡されたメッセージおよび/またはキーワード引数に変更を加えます。ここでの実装は extra としてコンストラクタに渡されたオブジェクトを取り、'extra' キーを使って kwargs に加えます。返り値は (msg, kwargs) というタプルで、(変更されているはずの) 渡された引数を含みます。
-
LoggerAdapter
は上記に加え Logger
のメソッド debug()
, info()
, warning()
, error()
, exception()
, critical()
, log()
, isEnabledFor()
をサポートします。これらは Logger
の対応するメソッドと同じシグニチャを持つため、2つのインスタンスは区別せずに利用出来ます。
バージョン 2.7 で変更: isEnabledFor()
が LoggerAdapter
に追加されました。このメソッドは元のロガーに処理を委譲します。
15.7.9. スレッドセーフ性¶
logging モジュールは、クライアントで特殊な作業を必要としない限りスレッドセーフになっています。このスレッドセーフ性はスレッドロックによって達成されています; モジュールの共有データへのアクセスを直列化するためのロックが一つ存在し、各ハンドラでも背後にある I/O へのアクセスを直列化するためにロックを生成します。
signal
モジュールを使用して非同期シグナルハンドラを実装している場合、そのようなハンドラからはログ記録を使用できないかもしれません。これは、 threading
モジュールにおけるロック実装が常にリエントラントではなく、そのようなシグナルハンドラから呼び出すことができないからです。
15.7.10. モジュールレベルの関数¶
上で述べたクラスに加えて、いくつかのモジュールレベルの関数が存在します。
-
logging.
getLogger
([name])¶ 指定された名前のロガーを返します。名前が指定されていなければ、ロガー階層のルート (root) にあるロガーを返します。name を指定する場合には、通常は "a", "a.b", "a.b.c.d" といったドット区切りの階層的な名前にします。名前の付け方はログ機能を使う開発者次第です。
与えられた名前に対して、この関数はどの呼び出しでも同じロガーインスタンスを返します。したがって、ロガーインスタンスをアプリケーションの各部でやりとりする必要はありません。
-
logging.
getLoggerClass
()¶ 標準の
Logger
クラスか、最後にsetLoggerClass()
に渡したクラスを返します。この関数は、新たなクラス定義の中で呼び出して、カスタマイズしたLogger
クラスのインストールが既に他のコードで適用したカスタマイズを取り消さないことを保証するために使われることがあります。例えば以下のようにします:class MyLogger(logging.getLoggerClass()): # ... override behaviour here
-
logging.
debug
(msg[, *args[, **kwargs]])¶ レベル
DEBUG
のメッセージをルートロガーで記録します。 msg はメッセージの書式化文字列で、 args は msg に文字列書式化演算子を使って取り込むための引数です。 (これは、書式化文字列の中でキーワードを使い、引数として単一の辞書を渡すことができる、ということを意味します。)キーワード引数 kwargs からは 2 つのキーワードが調べられます。一つ目は exc_info で、この値の評価値が false でない場合、例外情報をログメッセージに追加します。 (
sys.exc_info()
の返す形式の) 例外情報を表すタプルが与えられていれば、それをメッセージに使います。それ以外の場合には、sys.exc_info()
を呼び出して例外情報を取得します。ほかのキーワード引数は extra で、当該ログイベント用に作られる LogRecoed の __dict__ にユーザー定義属性を加えるのに使われる辞書を渡すために用いられます。これらの属性は好きなように使えます。たとえば、ログメッセージの一部にすることもできます。以下の例を見てください:
FORMAT = "%(asctime)-15s %(clientip)s %(user)-8s %(message)s" logging.basicConfig(format=FORMAT) d = {'clientip': '192.168.0.1', 'user': 'fbloggs'} logging.warning("Protocol problem: %s", "connection reset", extra=d)
これは以下のような出力を行います:
2006-02-08 22:20:02,165 192.168.0.1 fbloggs Protocol problem: connection reset
extra で渡される辞書のキーはロギングシステムで使われているものと衝突しないようにしなければなりません。 (どのキーがロギングシステムで使われているかについての詳細は
Formatter
のドキュメントを参照してください。)これらの属性をログメッセージに使うことにしたなら、少し注意が必要です。上の例では、 'clientip' と 'user' が LogRecord の属性辞書に含まれていることを期待した書式化文字列で
Formatter
がセットアップされています。もしこれらが欠けていると、書式化例外が発生してしまうためメッセージはログに残りません。したがってこの場合、常にこれらのキーを含む extra 辞書を渡す必要があります。このようなことは煩わしいかもしれませんが、この機能は限定された場面で使われるように意図しているものなのです。たとえば同じコードがいくつものコンテキストで実行されるマルチスレッドのサーバで、興味のある条件が現れるのがそのコンテキストに依存している (上の例で言えば、リモートのクライアント IP アドレスや認証されたユーザ名など)、というような場合です。そういった場面では、それ用の
Formatter
が特定のHandler
と共に使われるというのはよくあることです。バージョン 2.5 で変更: extra が追加されました。
-
logging.
warning
(msg[, *args[, **kwargs]])¶ レベル
WARNING
のメッセージをルートロガーで記録します。引数はdebug()
と同じように解釈されます。
-
logging.
critical
(msg[, *args[, **kwargs]])¶ レベル
CRITICAL
のメッセージをルートロガーで記録します。引数はdebug()
と同じように解釈されます。
-
logging.
exception
(msg[, *args[, **kwargs]])¶ レベル
ERROR
のメッセージをルートロガーで記録します。引数は、渡された exc_info の詳細が展開されないことを除いて、debug()
と同じように解釈されます。例外情報が常にログメッセージに追加されます。この関数は例外ハンドラからのみ呼び出されるべきです。
-
logging.
log
(level, msg[, *args[, **kwargs]])¶ レベル level のメッセージをルートロガーで記録します。その他の引数は
debug()
と同じように解釈されます。注釈
上述の便利なルートロガーに処理を委譲するモジュールレベル関数は
basicConfig()
を呼び出して、少なくとも 1 つのハンドラが利用できることを保証します。これにより Python の 2.7.1 以前や 3.2 以前のバージョンでは、スレッドが開始される 前に 少なくともひとつのハンドラがルートロガーに加えられるのでない限り、スレッド内で使うべき ではありません 。以前のバージョンの Python では、basicConfig()
のスレッドセーフ性の欠陥により、(珍しい状況下とはいえ)ハンドラがルートロガーに複数回加えられることがあり、ログ内のメッセージが重複するという予期しない結果をもたらすことがあります。
-
logging.
disable
(lvl)¶ 全てのロガーのレベル lvl を上書きし、これはロガー自身の出力レベルよりも優先されます。アプリケーション全体を横断するログ出力を一時的に調整する必要が生じたら、この関数は便利でしょう。これの効果は重大度 lvl 以下の全てのロギング呼び出しを無効にすることですので、INFO で呼び出しをすれば、INFO と DEBUG イベントが捨てられる一方で、重大度 WARNING 以上のものは、ロガーの有効レベルに基いて処理されます。
logging.disable(logging.NOTSET)
が呼び出されると、この上書きレベルは削除され、ログ出力は再び個々のロガーの有効レベルに依存するようになります。
-
logging.
addLevelName
(lvl, levelName)¶ 内部的な辞書の中でレベル lvl をテキスト levelName に関連付けます。これは例えば
Formatter
でメッセージを書式化する際のように、数字のレベルをテキスト表現に対応付ける際に用いられます。この関数は自作のレベルを定義するために使うこともできます。使われるレベルに対する唯一の制限は、レベルは正の整数でなくてはならず、メッセージの深刻度が上がるに従ってレベルの数も上がらなくてはならないということです。注釈
もしもあなたが独自のレベルを定義したいと考えるならば、どうか カスタムレベル のセクションをご参照下さいますようお願いします。
-
logging.
getLevelName
(lvl)¶ ログ記録レベル lvl のテキスト表現を返します。レベルが定義済みのレベル
CRITICAL
,ERROR
,WARNING
,INFO
,DEBUG
のいずれかである場合、対応する文字列が返されます。addLevelName()
を使ってレベルに名前を関連付けていた場合、 lvl に関連付けられた名前が返されます。定義済みのレベルに対応する数値を指定した場合、レベルに対応した文字列表現を返します。そうでない場合、文字列 "Level %s" % lvl を返します。注釈
たとえば
Logger
のインスタンスとハンドラへの設定をする場合には、数値のレベルを使用するべきです。この関数は、数値のレベルを、書式記述子%(levelname)s
(LogRecord 属性 参照)によって書式化されるログ出力の表示用レベル名に変換するのに使用されます。
-
logging.
makeLogRecord
(attrdict)¶ 属性が attrdict で定義された、新しい
LogRecord
インスタンスを生成して返します。この関数は、 pickle されたLogRecord
属性の辞書をソケットを介して送信し、受信端でLogRecord
インスタンスとして再構成する場合に便利です。
-
logging.
basicConfig
([**kwargs])¶ デフォルトの
Formatter
を持つStreamHandler
を生成してルートロガーに追加し、ロギングシステムの基本的な環境設定を行います。関数debug()
,info()
,warning()
,error()
,critical()
は、ルートロガーにハンドラが定義されていない場合に自動的にbasicConfig()
を呼び出します。この関数はルートロガーに設定されたハンドラがあれば何もしません。
バージョン 2.4 で変更: 以前は
basicConfig()
はキーワード引数を取りませんでした。注釈
この関数は、他のスレッドが開始される前にメインスレッドから呼び出されるべきです。Python の 2.7.1 や 3.2 以前のバージョンでは、この関数が複数のスレッドから呼ばれると(珍しい状況下とはいえ)ハンドラがルートロガーに複数回加えられることがあり、ログ内のメッセージが重複するという予期しない結果をもたらすことがあります。
以下のキーワード引数がサポートされます。
フォーマット 説明 filename
StreamHandler ではなく指定された名前で FileHandler が作られます。 filemode
Specifies the mode to open the file, if filename is specified (if filemode is unspecified, it defaults to 'a'). format
指定された書式化文字列をハンドラで使います。 datefmt
Use the specified date/time format. level
Set the root logger level to the specified level. stream
Use the specified stream to initialize the StreamHandler. Note that this argument is incompatible with 'filename' - if both are present, 'stream' is ignored.
-
logging.
shutdown
()¶ ロギングシステムに対して、バッファのフラッシュを行い、すべてのハンドラを閉じることで順次シャットダウンを行うように告知します。この関数はアプリケーションの終了時に呼ばれるべきであり、また呼び出し以降はそれ以上ロギングシステムを使ってはなりません。
-
logging.
setLoggerClass
(klass)¶ ロギングシステムに対して、ロガーをインスタンス化する際にクラス klass を使うように指示します。指定するクラスは引数として名前だけをとるようなメソッド
__init__()
を定義していなければならず、__init__()
ではLogger.__init__()
を呼び出さなければなりません。典型的な利用法として、この関数は自作のロガーを必要とするようなアプリケーションにおいて、他のロガーがインスタンス化される前にインスタンス化されます。
15.7.11. warnings モジュールとの統合¶
captureWarnings()
関数を使って、 logging
を warnings
モジュールと統合できます。
-
logging.
captureWarnings
(capture)¶ この関数は、logging による警告の補足を、有効にまたは無効にします。
capture が
True
なら、warnings
モジュールに発せられた警告は、ロギングシステムにリダイレクトされるようになります。具体的には、警告がwarnings.formatwarning()
でフォーマット化され、結果の文字列が'py.warnings'
という名のロガーに、WARNING
の重大度でロギングされるようになります。capture が
False
なら、警告のロギングシステムに対するリダイレクトは止められ、警告は元の (すなわち、captureWarnings(True)
が呼び出される前に有効だった) 送信先にリダイレクトされるようになります。
参考
logging.config
モジュール- logging モジュールの環境設定 API です。
logging.handlers
モジュール- logging モジュールに含まれる、便利なハンドラです。
- PEP 282 - ログシステム
- この機能を Python 標準ライブラリに含めることを述べた提案です。
- Original Python logging package
- これは、
logging
パッケージのオリジナルのソースです。このサイトから利用できるバージョンのパッケージは、logging
パッケージを標準ライブラリに含まない、 Python 1.5.2, 2.1.x および 2.2.x で使うのに適しています。