2011年7月2日土曜日

python:ログ出力(2)

ログ出力について、簡単なクラス化をしてみました。
python標準のロギング機能はバージョン2.3以降使用可能です。

#
# -*- coding:sjis -*-
#
import os,sys,logging

#ログ出力クラス
class LogW():
 """
 Properties:
  path: ログファイル名
  Logger:  ロガー(ログ割振り機構)
 Attention:
  最低メッセージレベル以上のメッセージをログや画面に出力する。
 """
 def __init__(self, sLog="", bDel=True, bLogLV=10, bGamenLV=20):
  """コンストラクタ
  Args:
   sLog: ログファイルフルパス。未指定時はソース".py"→".log"
   bDel: 初期既存時削除か(bool)
   bLogLV: ログファイル出力対象の最低メッセージレベル
   bGamenLV: 画面表示対象の最低メッセージレベル
  Attention:
   レベ:0=NOTSET,10=DEBUG,20=INFO,30=WARNING,40=ERROR,50=CRITICAL
  """
  #ログファイル名
  if sLog: self.path = sLog
  else: self.path = sys.argv[0][:-3]+".log" #".py"→".log"
  if bDel and os.path.isfile(self.path): os.remove(self.path)
  #レベル名称の変更
  for level, name in zip([10,20,30,40],["_","I","W","E"]):
   logging.addLevelName(level, name)
  #ロガー(ログ割振り機構)
  self.Logger = logging.getLogger("")
  #ログファイルのハンドラー
  self.logfilehdlr = logging.FileHandler(self.path)
  self.Logger.addHandler(self.logfilehdlr)
  #画面のハンドラー
  self.consolehdlr = logging.StreamHandler()
  self.Logger.addHandler(self.consolehdlr)
  #ルートロガーは全メッセージが通るようにしておく
  logging.root.setLevel(logging.NOTSET)
  #出力レベルの設定
  self.setlevel(bLogLV, bGamenLV)

 #デストラクタ
 def __del__(self):
  self = None

 def setformat(self, T=True, V=False):
  """メッセージ書式の設定
  Args:
   T: 日時出力(bool)
   V: レベル名称出力(bool)
  """
  s = ""
  if T: s = "%(asctime)s "
  if V: s+= "%(levelname)s "
  s+= "%(message)s"
  formatter = logging.Formatter(s, "%Y/%m/%d %H:%M:%S")
  self.logfilehdlr.setFormatter(formatter)
  self.consolehdlr.setFormatter(formatter)

 def setlevel(self, iLogV=10, iGamenV=20):
  """出力レベルの設定
  Args:
   iLogV: ログファイル出力対象の最低メッセージレベル
   iGamenV: 画面表示対象の最低メッセージレベル
  Attention:
   レベ:0=NOTSET,10=DEBUG,20=INFO,30=WARNING,40=ERROR,50=CRITICAL
  """
  self.logfilehdlr.setLevel(iLogV)
  self.consolehdlr.setLevel(iGamenV)

 def I(self, msg="", T=True, V=False, G=True, L=True):
  """情報レベルメッセージの出力
  Args:
   msg: メッセージ
   T: 日時出力(bool)
   V: レベル名称出力(bool)
   G: 画面出力(bool)
   L: ログ出力(bool)
  """
  if not G: self.setlevel(iGamenV=100) #画面出力可否
  if not L: self.setlevel(iLogV=100)
  self.setformat(T, V)
  self.Logger.info(msg)
  self.setlevel() #画面出力可否、ログ出力可否をクリア

if __name__=="__main__":
 log = LogW()
 log.I("a:日時出力、ログ抑止、画面出力",L=False)
 log.I("b:日時出力、ログ出力、画面抑止",G=False)
 log.I("c:日時抑止、ログ出力、画面出力",T=False)
 log.I("d:日時出力、ログ出力、画面出力")
 log.setformat(V=True) #レベル名称出力可
 log.Logger.info("情報レベル")
 log.Logger.warning("警告レベル")
 log = None

----------

結果

○画面(標準出力)
ケースa、c、dを出力。

2011/07/02 07:45:27 a:日時出力、ログ抑止、画面出力
c:日時抑止、ログ出力、画面出力
2011/07/02 07:45:27 d:日時出力、ログ出力、画面出力
2011/07/02 07:45:27 I 情報レベル
2011/07/02 07:45:27 W 警告レベル



○ログファイル
ケースb、c、dを出力。2011/07/02 07:45:27 b:日時出力、ログ出力、画面抑止
c:日時抑止、ログ出力、画面出力
2011/07/02 07:45:27 d:日時出力、ログ出力、画面出力
2011/07/02 07:45:27 I 情報レベル
2011/07/02 07:45:27 W 警告レベル


なお、関係する記事は以下です。
python:ログ出力

0 件のコメント:

コメントを投稿