loggingモジュールのあれこれ

| | Comments (0) | TrackBacks (0)
Pythonのloggingモジュールについては過去の記事で書かれていますが、その後の勉強でいろいろと分かったことがありました。

多少ハマってしまったこともあったため、ここにまとめてみたいと思います。

1.設定ファイルの作り方
2.設定ファイルで設定してみる
3.設定ファイルを書くときの注意
4.おまけ

1.設定ファイルの作り方

設定ファイルとは

loggingモジュールをインポートした直後は "root" ロガー以外は設定が行われていません。そのため

log = logging.getLogger("mylogger")
log.debug("hello, logging
module!")

と打ち込んでも、どこに書き込めばいいのか、どのレベル以上のログを扱うのかといった設定を "mylogger" に対して何も行っていないため
画面はおろか、ファイルにも "hello, logging module!" のログは書き込まれません。

そこで、書き込み先や出力レベルなどを設定する必要があります。
たとえば、先ほどの "mylogger" にdebug以上のレベルのログを画面に書き込む設定を行ってみましょう。

log.setLevel(logging.DEBUG) # debug以上のレベルのログを書き込む

# 書き込み先や、ログの出力フォーマットを決める "handler" を作る
handler = logging.StreamHandler(sys.stdout)                                   # 標準出力にログを書き込む
handler.setFormatter(logging.Formatter("%(asctime)s %(message)s")) # 出力フォーマットを設定

# "mylogger" に "handler" を通してログ出力できるようにする
log.addHandler(handler) # "mylogger" に "handler" を追加

さあ、これで準備は整いました。さっそく挨拶をしてみましょう。
log.debug("hello, logging module!")
2008-10-23 00:48:31,864 hello, logging module!

表示されましたでしょうか?
"root" ロガーは最初からこのような設定が済んでいるために

rootlog = logging.getLogger("root")
rootlog.warn("hello, root logger!")

WARNING:root:hello, root logger!

と "handler" の設定を行わなくても表示させることができますが、新しいロガーを作るときはこのような設定を行う必要があります。


2.設定ファイルで設定してみる

 

新しいロガーを使えるようになるまでの流れをまとめてみました。
 
import logging
import sys
 
log = logging.getLogger("mylogger")
log.setLevel(logging.DEBUG)
 
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(logging.Formatter("%(asctime)s %(message)s"))
 
log.addHandler(handler)
 
大した量のコードではありませんが、ロガーを新しく作るたびにこんなコードを書くのは面倒です。
 
そこで、設定ファイルを使うことでこの面倒なコードのコピペから脱出しましょう。
上のコードと同じ設定を行うときの設定ファイルは以下のようになります。
 

[loggers]
keys=root,mylogger
 
[handlers]
keys=roothandler,myhandler
 
[formatters]
keys=default,myformat
 
[formatter_default]
format=%(asctime)s %(levelname)s %(message)s
datefmt=
 
[formatter_myformat]
class=logging.Formatter
format=%(asctime)s %(message)s
datefmt=
 
[handler_roothandler]
class=StreamHandler
args=(sys.stdout,)
formatter=default
 
[handler_myhandler]
class=StreamHandler
args=(sys.stdout,)
formatter=myformat
 
[logger_root]
level=DEBUG
handlers=roothandler
 
[logger_mylogger]
level=DEBUG
handlers=myhandler
propagate=0
qualname=mylogger
</pre>

formatter、handler、loggerの3つの要素についての設定を行っています。

[formatter_...]
ログのフォーマットを設定します。
%(asctime)s などを使ってどんな情報をログに書き込むかを決めていきます。
datefmt= は、%(asctime)s の形式を決めるものです。
http://www.python.jp/doc/release/lib/module-time.html に、どんなものが使えるかが載っています。

[handler_...]
ハンドラの設定を行います。
ログの出力先を決めたり、使用するフォーマットを決める部分です。

[logger_...]
ロガーの設定を行います。
ログの出力レベルや、使用するハンドラ、ロガーを取得するときの名前を設定します。
親子関係を持ったロガーの場合、子のロガーで書き込んだログが親のロガーでも出力されます。
その機能を使うかどうかの設定を propagate で行います。上位のロガーでも同じ内容を書き出したいときは
propagate = 1
と設定します。


3.設定ファイルを書くときの注意

実際に私が設定ファイルを書いているときに嵌ったことをいくつかあげておきます。

1. 設定ファイルには必ず "root" ロガーの設定を行う
最初から設定が行われている "root" ロガー。設定ファイルにまで書かなくてもいいだろう、その分減って見やすくなるし。
...そう思い、 "root" ロガーの設定を行わずに設定ファイルを書き、loggingの実験を行いました。
そのときの私は、まさかそんなことで2時間も悩むことになるとは思いもしませんでした。

2.args=(sys.stdout,) の ',' を忘れない
インタープリタ上では
StreamHandler(sys.stdout)
で動きますが、設定ファイルに書き込む際には(sys.stdout,)としなければ
エラーになってしまいます。
タプルになるように書かないといけないのではないかと思います。

実はライブラリリファレンスに書いてあることばかりだったりします。
やっぱり困ったときは基本に立ち返ることも重要ですね。


4.おまけ
設定ファイルのひな形

面倒なrootロガーの設定を済ませたものを載せておきます。
DEBUGレベル以上のログを画面に出力する設定になっています。
これに、使いたいロガーの設定を付け足していけば設定ファイルが出来上がります。

[loggers]
keys=root

[formatters]
keys=default

[handlers]
keys=default

[formatter_default]
format=%(asctime)s %(name)s %(levelname)s %(message)s
datefmt=

[handler_default]
class=StreamHandler
formatter=default
args=(sys.stdout,)

[logger_root]
level=DEBUG
handlers=default

0 TrackBacks

Listed below are links to blogs that reference this entry: loggingモジュールのあれこれ.

TrackBack URL for this entry: http://lab.hde.co.jp/blog/mt-tb.cgi/76

Leave a comment

About this Entry

This page contains a single entry by hayashi published on December 18, 2008 10:13 AM.

TwistedをRPM化する小ネタ was the previous entry in this blog.

日経225のSPF対応状況(2008年12月) is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.