pythonでのロギング機能を実装してみる。(設定ファイル読み込んでloggerで出力)
pythonを勉強しはじめの頃はprintでログ出力していたが、そろそろ規模も大きくなってきて運用も視野に入れpythonでのロギング機能を実装してみる。
標準出力と/tmp/test.logの両方にログ出力する場合の例
ログレベルはDEBUG
from logging import getLogger,Formatter,StreamHandler,FileHandler,DEBUG logger = getLogger("test") formatter = Formatter('%(asctime)s [%(levelname)s] [%(filename)s: %(funcName)s: %(lineno)d] %(message)s') handlerSh = StreamHandler() handlerFile = FileHandler("c:/tmp/test.log") handlerSh.setFormatter(formatter) handlerSh.setLevel(DEBUG) handlerFile.setFormatter(formatter) handlerFile.setLevel(DEBUG) logger.setLevel(DEBUG) logger.addHandler(handlerSh) logger.addHandler(handlerFile)
上記だと、全てのPythonファイルに記述しなくていけないので面倒なので設定ファイル読み込み版にする。
Python2.7から導入されたというYAML形式が記述しやすい
インストール
pip install PyYAML
前述と設定内容は変わるけどこんな感じで設定。
logging.conf
version: 1 formatters: custmoFormatter: format: '[%(asctime)s] %(levelname)s - %(filename)s#%(funcName)s:%(lineno)d: %(message)s' datefmt: '%Y/%m/%d %H:%M:%S' loggers: test: handlers: [fileRotatingHandler,consoleHandler] level: DEBUG qualname: test propagate: no file: handlers: [fileRotatingHandler] level: DEBUG qualname: file propagate: no console: handlers: [consoleHandler] level: DEBUG qualname: console propagate: no handlers: fileRotatingHandler: formatter: custmoFormatter class: logging.handlers.TimedRotatingFileHandler level: DEBUG filename: c:/tmp/test.log encoding: utf8 when: 'D' interval: 1 backupCount: 14 consoleHandler: class: logging.StreamHandler level: DEBUG formatter: custmoFormatter stream: ext://sys.stdout root: level: DEBUG handlers: [fileRotatingHandler,consoleHandler]
最後のrootを忘れると動かないので注意。
インデントが不正だと「'NoneType' object is not iterable」エラーが発生するので注意。
ログ出力するPythonコード側はこんな感じ
import yaml from logging import config,getLogger config.dictConfig(yaml.load(open("logging.conf", encoding='UTF-8').read())) logger = getLogger("test") logger.debug("output logging test!!")
config.dictConfigとかの処理は共通初期化モジュールとかに分離したい所。
ちなみに、Pythonではエラーログで例外情報出力用のメソッドがあるらしい、便利。
try: dosomething() except (KeyError, ValueError) as err: logger.exception('Error dosomething: %s', err)
参考
Pythonでログ出力についての考え方参考なった。
http://qiita.com/amedama/items/b856b2f30c2f38665701
設定ファイル記述に関して参考
http://qiita.com/petitviolet/items/86a3cc74d35fd9f6c96c
http://symfoware.blog68.fc2.com/blog-entry-888.html
例外情報出力
http://ikeikeikeike.hatenablog.com/entry/2014/02/07/113400
ログフォーマットは公式より
http://docs.python.jp/2/library/logging.html#logrecord-attributes