Symfoware

Symfowareについての考察blog

Python logging 設定ファイルによるログ出力の設定

Pythonのloggingについて勉強中です。
Python loggingモジュールの基本的な使い方
Python logging 各種出力ハンドラーの使い方について
Python logging 複数のロガー、ハンドラーの使用方法


今回は、ログファイルの出力を設定ファイルで指定する方法を調べてみます。





設定ファイルの記載方法と読み込み



設定ファイルの記載方法はこちらを参考にしました。
ロギングの環境設定

Python 2.7以降から、YAML形式の設定ファイルがサポートされているようですが、
今回は旧来の設定ファイルで試してみることにします。


最初のサンプルとして、rootロガーを使用。
ログレベルはDEBUG。
コンソールにログを出力する設定です。


[loggers]
keys=root

[handlers]
keys=consoleHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)

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




私の中の理解を図にしてみました。

33_001_20111231153050.png


まず、loggers,handlers,formattersの3つの指定を行う。
ここで指定するのは名前だけ。

次に、各々の基本設定で指定した名前を使用して、命名する
loggers_xxx,handlers_xxx,formatter_xxx
これらの詳細設定を行うという感じです。



プログラムから設定ファイルを読み込むには、

logging.config.fileConfig


を使用します。


サンプルプログラム全体では以下のようになりました。

  1. # -*- coding:utf-8 -*-
  2. import logging
  3. import logging.config
  4. # 設定ファイル読み込み
  5. logging.config.fileConfig('logging.conf')
  6. # rootロガーを取得
  7. log = logging.getLogger()
  8. log.debug('debugメッセージ')
  9. log.info('infoメッセージ')
  10. log.warn('warnメッセージ')
  11. log.error('errorメッセージ')
  12. log.critical('criticalメッセージ')




実行してみると、コンソールにログが出力されます。

$ python sample.py
2011-12-31 13:50:41,789 - root - DEBUG - debugメッセージ
2011-12-31 13:50:41,789 - root - INFO - infoメッセージ
2011-12-31 13:50:41,789 - root - WARNING - warnメッセージ
2011-12-31 13:50:41,790 - root - ERROR - errorメッセージ
2011-12-31 13:50:41,790 - root - CRITICAL - criticalメッセージ











名前付きロガーのサンプル



Python logging 複数のロガー、ハンドラーの使用方法
ここで試した最初のサンプルを設定ファイルに置き換えてみます。

サンプルは、sub1とsub2で出力するロガーを変更するものでした。

まず、サンプルプログラムは以下の3つ。

sub1、sub2を呼び出すsample.py

  1. # -*- coding:utf-8 -*-
  2. import logging.config
  3. import sub1
  4. import sub2
  5. # 設定ファイル読み込み
  6. logging.config.fileConfig('logging.conf')
  7. #テストメソッドを呼び出す
  8. sub1.sub1_func()
  9. sub2.sub2_func()




呼び出される側のsub1.pyとsub2.py

  1. # -*- coding:utf-8 -*-
  2. import logging
  3. log = logging.getLogger("sub1")
  4. def sub1_func():
  5.     log.debug('debugメッセージ')
  6.     log.info('infoメッセージ')
  7.     log.warn('warnメッセージ')
  8.     log.error('errorメッセージ')
  9.     log.critical('criticalメッセージ')





  1. # -*- coding:utf-8 -*-
  2. import logging
  3. log = logging.getLogger("sub2")
  4. def sub2_func():
  5.     log.debug('debugメッセージ')
  6.     log.info('infoメッセージ')
  7.     log.warn('warnメッセージ')
  8.     log.error('errorメッセージ')
  9.     log.critical('criticalメッセージ')




設定ファイルlogging.confはこんな感じになります。

[loggers]
keys=root,sub1,sub2

[handlers]
keys=consoleHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=DEBUG
handlers=

[logger_sub1]
level=DEBUG
handlers=consoleHandler
qualname=sub1

[logger_sub2]
level=DEBUG
handlers=consoleHandler
qualname=sub2

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)

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





rootロガーは使用しないのですが、設定ファイルに記載していないと、
設定ファイル読み込み時にこんなエラーが発生しました。

Traceback (most recent call last):
File "sample.py", line 9, in <module>
    logging.config.fileConfig('logging.conf')
File "/usr/lib/python2.7/logging/config.py", line 79, in fileConfig
    _install_loggers(cp, handlers, disable_existing_loggers)
File "/usr/lib/python2.7/logging/config.py", line 183, in _install_loggers
    llist.remove("root")
ValueError: list.remove(x): x not in list




必須パラメーターらしいので、rootロガーを宣言し、

[logger_root]
level=DEBUG
handlers=


このように、ロガーのhandlersに何も指定しないことで、rootロガーによる
ログの出力をキャンセルしています。

また、qualnameに指定した値がロガーの名前になるようです。


実行してみると、想定通りの動作になりました。

$ python sample.py
2011-12-31 14:48:51,622 - sub1 - DEBUG - debugメッセージ
2011-12-31 14:48:51,622 - sub1 - INFO - infoメッセージ
2011-12-31 14:48:51,622 - sub1 - WARNING - warnメッセージ
2011-12-31 14:48:51,622 - sub1 - ERROR - errorメッセージ
2011-12-31 14:48:51,622 - sub1 - CRITICAL - criticalメッセージ
2011-12-31 14:48:51,622 - sub2 - DEBUG - debugメッセージ
2011-12-31 14:48:51,623 - sub2 - INFO - infoメッセージ
2011-12-31 14:48:51,623 - sub2 - WARNING - warnメッセージ
2011-12-31 14:48:51,623 - sub2 - ERROR - errorメッセージ
2011-12-31 14:48:51,623 - sub2 - CRITICAL - criticalメッセージ





試しに、設定ファイルの一部を変更し、sub2のログレベルをERRORに変更してみます。


[logger_sub2]
level=ERROR
handlers=consoleHandler
qualname=sub2




実行してみると、sub2のログはERROR以上しか表示されなくなりました。

$ python sample.py
2011-12-31 14:51:27,826 - sub1 - DEBUG - debugメッセージ
2011-12-31 14:51:27,827 - sub1 - INFO - infoメッセージ
2011-12-31 14:51:27,827 - sub1 - WARNING - warnメッセージ
2011-12-31 14:51:27,827 - sub1 - ERROR - errorメッセージ
2011-12-31 14:51:27,827 - sub1 - CRITICAL - criticalメッセージ
2011-12-31 14:51:27,827 - sub2 - ERROR - errorメッセージ
2011-12-31 14:51:27,827 - sub2 - CRITICAL - criticalメッセージ













ロガーに複数のハンドラーを指定するサンプル



Python logging 複数のロガー、ハンドラーの使用方法
ここで試した二番目のサンプルを設定ファイルに置き換えてみます。

sub1とsub2のログはコンソールに出力。
加えてsub2のログはファイルにも出力するパターンです。


[loggers]
keys=root,sub1,sub2

[handlers]
keys=consoleHandler,fileHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=DEBUG
handlers=

[logger_sub1]
level=DEBUG
handlers=consoleHandler
qualname=sub1

[logger_sub2]
level=DEBUG
handlers=consoleHandler,fileHandler
qualname=sub2

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)

[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=simpleFormatter
args=('log.txt', 'a')



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




設定ファイルの編集だけで、sub2のログがファイルにも出力されるようになったと思います。




関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2011/12/31(土) 15:31:18|
  2. Python
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
次のページ