ロギング
- DEBUGレベルはファイルへ、INFOレベル以上は標準出力にログさせたい場合
- 基本は logging.basicConfig で設定する
- 標準出力用のハンドラ(console)をStreamHandler()で設定する
- consoleハンドラ を グローバルななロガー(?) (logging.getLogger()) に追加する
- ファイルへの出力は、FileHandler('filename')を使うことも可能だが、この場合だと日付フォーマットが指定できないので却下
import logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)-8s %(name)-12s %(module)s.%(funcName)-20s %(message)s', datefmt='%Y-%m-%d %H:%M:%S', filename='example.log', filemode='a') console = logging.StreamHandler() console.setLevel(logging.INFO) formatter = logging.Formatter('%(levelname)-8s %(name)-12s %(module)s.%(funcName)-20s %(message)s') console.setFormatter(formatter) logging.getLogger('').addHandler(console) ## __________________________________________________ class LogExDayo(object): ## __________________________________________________ def __init__(self): ... self.logger = logging.getLogger('LogExDayo') self.logger.debug('-' * 50) ## __________________________________________________ def read(self, ifn): ## exit if file does not exists if not os.path.exists(ifn): self.logger.error('file "%s" does not exist.', ifn) sys.exit(-1) ## read file ## ... ## __________________________________________________ def run(self): self.logger.info('start') # ... process ... self.logger.info('finished) ## __________________________________________________ if __name__ == '__main__': l = LogExDayo() l.read('read_this_file.txt') l.run()
basicConfigで設定できる項目
- basicConfigは、debug()や、info()などが呼ばれる前に設定して置かなければいけない
>>> import logging >>> help(logging.basicConfig)
attribute | default value | description |
---|---|---|
filename | - | ログ出力先のファイル名を指定; streamより優先される |
filemode | a | ファイルに書き込む方法を指定; [a, w] |
format | logging.BASIC_FORMAT | 書式設定; 詳細は help(logging.Formatter)参照 |
datefmt | - | 時刻(asctime)の書式設定 |
level | logging.WARNING | ログレベルの設定; [NOTSET, DEBUG, INFO, WARNING, CRITICAL, FATAL] |
stream | sys.stderr | StreamHandlerを設定; [sys.stderr, sys.stdout] |
- helpに書いてあったけれど、streamでファイルを指定することも可能だけれど、ファイルクローズされないのでやらないほうがいい
logging.basicConfig(stream=open(filename, 'w')) ## <== ファイルクローズ機能はない
## オプション解析は、optparse.OptionParserを使ってみる parser = OptionParser(usage) parser.add_option(-l, --log, dest='loglevel', help='set log level. ex) --log=DEBUG or --log=debug.') ## これ以降で、オプションのloglevelの値を確認し、basicConfigに設定 ## 値が正しくない場合は、ValueErrorでエラー処理 numeric_level = getattr(logging, loglevel.upper(), None) if not is instance(numeric_level, int): raise ValueError('Invalid log level : %s' % log level) logging.basicConfig(level=numeric_level, ...)
ログレベルの設定
- 2つの方法で、ログ出力のレベルを設定できる
- loggingの初期値として設定
- logging.Loggerオブジェクト(以下Loggerオブジェクト)を作成し、それに対して設定
- Loggerオブジェクトはlogging.getLogger(name)でインスタンス化する決まり
## loggingモジュールの初期設定 logging.basicConfig(level=logging.DEBUG) ## Loggerオブジェクトを作ってから設定 logger = logging.getLogger('somelogger') logger.setLevel(logging.DEBUG)
- 設定したログレベル以上のメッセージが出力される
- DEBUGの場合:DEBUG, INFO, ERROR, CRITICAL, FATAL
- ERRORの場合:ERROR, CRITICAL, FATAL
- 出力レベルは、各ファイルハンドラ(i.e. ログファイル、コンソール)に応じて変更可能
logging.NOTSET # = 0 logging.DEBUG # = 10 logging.INFO # = 20 logging.WARNING # = 30 logging.ERROR # = 40 logging.CRITICAL # = 50 logging.FATAL # = 50
ハンドラの設定
- ログメッセージの表示先、記録先を、ログレベルに応じて切り替える場合に使う
- StreamHandler
- FileHandler
ログ設定ファイル
- fileConfig()
- dictConfig()