Python標準ライブライリを使い倒す(logging編)

| | Comments (0) | TrackBacks (0)
Javaにはlog4j、.NETにはlog4netがあるように当然Pythonにもログ機能(以下からloggingとします。)は存在しますが、Pythonの場合は標準ライブラリにすでに組み込まれています。
今回はその機能を使用したサンプルを紹介します。

loggingではいくつかのログ出力方式を指定することが可能ですが、今回はログファイルのサイズ指定とローテート指定の行える「RotatingFileHandler」を使用してサンプルを作成します。

その他のログ出力方式は、Python用ロギング機能 を参照してみてください。

今回は、ログ出力用のプログラムファイル(log.py)と設定ファイル(log.conf)を作成します。

注) 設定ファイルを使用せずにプログラムファイルで設定を行うことも可能ですが、一般的にログ設定ファイルを作成しますので今回は設定ファイルを作成します。
また、loggers:root(rootはすべてのログの頂点ですので、appのログも出力します。)は標準出力に出力されます。
rootのログがいらない場合は、FileHandlerで/dev/nullに設定しておくほうがよいかもしれません。


log.conf(設定ファイル)

  1 [loggers]
  2 keys=root,app
  3 
  4 [formatters]
  5 keys=default,basic
  6 
  7 [handlers]
  8 keys=frotate,default
  9 
 10 [formatter_default]
 11 format=%(asctime)s %(levelname)s %(message)s
 12 datefmt=
 13 
 14 [formatter_basic]
 15 class=logging.Formatter
 16 format=%(name)s %(levelno)s %(levelname)s %(pathname)s %(filename)s %(module)s %(lineno)d %(created)f %(asctime)s %(msecs)d %(relativeCreated)d %(thread)d %    (process)d %(message)s
 17 datefmt=%d/%m/%Y %H:%M:%S
 18 
 19 [handler_frotate]
 20 class=handlers.RotatingFileHandler
 21 level=DEBUG
 22 formatter=basic
 23 args=('./app.log', 'a', (5*1024*1024), 5)
 24 
 25 [handler_default]
 26 class=StreamHandler
 27 level=NOTSET
 28 formatter=default
 29 args=(sys.stdout,)
 30 
 31 [logger_app]
 32 level=DEBUG
 33 handlers=frotate
 34 qualname=app
 35 
 36 [logger_root]
 37 level=NOTSET
 38 handlers=default


設定ファイルの説明

設定ファイルのフォーマットはPythonライブラリのConfigParser(設定ファイルの構文解析器)形式です。

基本的な構成は以下になります。

  1. [loggers] : プログラムで指定するログターゲットを指定します。(ここを頂点としたツリー構成で作成してください。)
        keys : ターゲットを指定します。(hoge.fooのような階層指定も可能です。)
  2. [formatters] : 使用したいフォーマットを指定します。
        keys : 4の[*]を指定します。
  3. [handlers] : 使用したいハンドル名を指定します。
        keys : 5の[*]を指定します。
  4. [formatter_*] : ログ出力のフォーマットを決定します。
        class : フォーマットを行うクラスを指定します。(自分で拡張でもしないかぎりは、logging.Formatterでいいと思います)
        format : フォーマットパターンを指定します。(文字列表記)
    使用できるレコードはPython ライブラリリファレンス 6.29.6 Formatter オブジェクトで確認できます。
        datefmt : 日付フォーマットを指定します。
    使用できる表記形式はPython ライブラリリファレンス 6.11 time -- 時刻データへのアクセスと変換のstrftimeメソッドに記載されています。
  5. [handler_*] : どんな形式でログを作成するかを決定します。
        class : ハンドラを指定します。(今回はFileHandler、RotatingFileHandlerを使用します)
        formatter : フォーマット(4の[*]を指定します。)
        args : 各ハンドラが使用するコンストラクタの引数に使用されます。
    くわしくはソース(/usr/lib/python/logging/handlers.py)のコンストラクタを読むほうがわかりやすいと思います。

    今回は深く考えずに以下を設定してみてください。(RotatingFileHandlerの場合)
        第1引数 : ログファイル名
        第2引数 : ファイルモード
        第3引数 : 最大ファイルサイズ(ここで指定したファイルサイズを超えるとローテートされます)指定します。
        第4引数 : ローテートされたファイルの保存ファイル数を指定します。この数を超えたファイルは削除されます。
  6. [logger_*] : 使用するログを指定します。
        level : ログレベル(注釈1を参照のこと)
        handlers : ハンドラ(5の[*]を指定します。)
        qualname : ロガー名

注釈1:ログレベル
ログレベルは以下になります。
  1. debug
  2. info
  3. warn
  4. error
  5. critical

warnを指定するとそれより下のレベルのinfo,debugは出力されなくなります。
開発中、運用中などの場面で使い分けるとよいでしょう。


log.py(プログラムファイル)

  1 import logging
  2 import logging.config
  3 
  4 LOGGING_CONF = 'log.conf' # 今回使用する設定ファイルパスを指定します。
  5 logging.config.fileConfig(LOGGING_CONF) # 設定ファイルをセットします。
  6 logger = logging.getLogger("root") # ロガーのkeyをrootにします。(後述)
  7 
  8 logger.debug("logger=root : debug message") # debugレベルのログ出力を行います。
  9 logger.info("logger=root : info message") # infoレベルのログ出力を行います。
 10 logger.warn("logger=root : warn message") # warnレベルのログ出力を行います。
 11 logger.error("logger=root : error message") # errorレベルのログ出力を行います。
 12 logger.critical("logger=root : critical message") # criticalレベルのログ出力を行います。
 13 
 14 logger1 = logging.getLogger("app") # ロガーのkeyをappにします。(後述)
 15 for i in range(10000):
 16     logger1.debug("logger=app : debug message") # debugレベルのログ出力を行います。
 17     logger1.info("logger=app : info message") # infoレベルのログ出力を行います。
 18     logger1.warn("logger=app : warn message") # warnレベルのログ出力を行います。
 19     logger1.error("logger=app : error message") # errorレベルのログ出力を行います。
 20     logger1.critical("logger=app : critical message") # criticalレベルのログ出力を行います。


プログラムファイルの説明

5行目 : 設定ファイルをセットします。
6行目 : ログのターゲットを指定します。設定ファイルの[logging]
15-20行目 : 実際にローテートされるか確認するコードです。



サンプルの実行

$ python log.py 
default 2008-02-15 22:35:24,360 DEBUG logger=root : debug message
default 2008-02-15 22:35:24,360 INFO logger=root : info message
default 2008-02-15 22:35:24,361 WARNING logger=root : warn message
default 2008-02-15 22:35:24,361 ERROR logger=root : error message
default 2008-02-15 22:35:24,361 CRITICAL logger=root : critical message
default 2008-02-15 22:35:24,361 DEBUG logger=app : debug message
default 2008-02-15 22:35:24,362 INFO logger=app : info message
default 2008-02-15 22:35:24,362 WARNING logger=app : warn message
default 2008-02-15 22:35:24,363 ERROR logger=app : error message
default 2008-02-15 22:35:24,363 CRITICAL logger=app : critical message

※   同一フォルダにapp.log*ができています。そちらがlogger:appで指定したログです。


終りに

簡単にログ出力が行えることが分かってもらえたと思います。
また、高度なログ出力SMTP、Socketを使用してのログ出力などバリエーション豊富ですので、
機会があれば他のログ出力もためしてみてください。

0 TrackBacks

Listed below are links to blogs that reference this entry: Python標準ライブライリを使い倒す(logging編).

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

Leave a comment

About this Entry

This page contains a single entry by kei published on February 15, 2008 11:37 AM.

jQuery(2) : プラグインを使おう was the previous entry in this blog.

Tracを使ったバグ管理システム(1) : バグ管理システムとは is the next entry in this blog.

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