loggingで遊ぶ

JavaLog4jPython版loggingで遊んでみた。
というより、さっくり使おうとしたら、思ったように使えなくてはまっていたのは内緒の話だ。

ベーシックにつかう

ソース

# encode=utf-8

import logging

logging.warn('I am man.')
logging.info('You are man.')
logging.debug('Python!!')

出力結果

WARNING:root:I am man.

おっ? warnしかでない。
大丈夫。想定内だ。

これはデフォルトのloggerのログレベルがwarn以上しか出力しないから
標準のログレベルはソースコード(PYTHONPATH\Lib\logging\__init__.py:113 - 120)を見ると

CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0

となってるのでWARN以上のERROR、CRITICALは出力される。

再度実験。

# encode=utf-8

import sys,os,logging

logging.critical('danger!!')
logging.error('ERRROR!!')
logging.warn('I am man.')
logging.info('You are man.')
logging.debug('Python!!')
>>> 
CRITICAL:root:danger!!
ERROR:root:ERRROR!!
WARNING:root:I am man.

じゃあここで、infoとdebugを出してみる。
「logging.basicConfig(level=logging.DEBUG)」を追加してdebug以上でも出力させる。
ソース

# encode=utf-8

import sys,os,logging

logging.basicConfig(level=logging.DEBUG)
logging.critical('danger!!')
logging.error('ERRROR!!')
logging.warn('I am man.')
logging.info('You are man.')
logging.debug('Python!!')

出力

CRITICAL:root:danger!!
ERROR:root:ERRROR!!
WARNING:root:I am man.
INFO:root:You are man.
DEBUG:root:Python!!

おし、ばっちり!!

ファイルに出力して使う。

このままだと、printデバッグと変らないので、
ファイル出力してみる。

# encode=utf-8

import sys,os,logging

logging.basicConfig(
level=logging.DEBUG, 
format='%(asctime)s %(levelname)s %(message)s', 
filename=r'C:\log.txt', 
filemode='w')

logging.critical('danger!!')
logging.error('ERRROR!!')
logging.warn('I am man.')
logging.info('You are man.')
logging.debug('Python!!')

Cドライブにlog.txtが出来たので開いてみる。

2008-05-26 23:02:00,687 CRITICAL danger!!
2008-05-26 23:02:00,687 ERROR ERRROR!!
2008-05-26 23:02:00,687 WARNING I am man.
2008-05-26 23:02:00,687 INFO You are man.
2008-05-26 23:02:00,687 DEBUG Python!!

ばっちり!!

マイロガーとして使う

まあ、ここまでなら別になんてことはないんですが、
例えば、 warn,error,criticalはコンソールに、debug,infoはファイルに書き出すという
2種類のログを同時に取ってみる。

ソース

# encode=utf-8
import sys,os,logging

# コンソールに出力
logging.basicConfig(level=logging.WARN, format='%(asctime)s %(levelname)s %(message)s')

logging.critical('danger!!')
logging.error('ERRROR!!')
logging.warn('I am man.')
logging.info('You are man.')
logging.debug('Python!!')

# ファイルに出力
logfile = logging.FileHandler(r'C:\Mylogger.txt')
format = logging.Formatter('[%(filename)s:%(lineno)d] %(asctime)s %(levelname)s %(message)s')
logfile.setFormatter(format)
logging.getLogger('MyLogger').addHandler(logfile)
log = logging.getLogger('MyLogger')
log.setLevel(logging.DEBUG)

log.critical('MyLogger CRITICAL')
log.error('MyLogger ERROR')
log.warn('MyLogger WARN')
log.info('MyLogger INFO')
log.debug('MyLogger DEBUG')

コンソール出力

2008-05-26 23:37:56,155 CRITICAL danger!!
2008-05-26 23:37:56,155 ERROR ERRROR!!
2008-05-26 23:37:56,171 WARNING I am man.
2008-05-26 23:37:56,171 CRITICAL MyLogger CRITICAL
2008-05-26 23:37:56,171 ERROR MyLogger ERROR
2008-05-26 23:37:56,171 WARNING MyLogger WARN
2008-05-26 23:37:56,187 INFO MyLogger INFO
2008-05-26 23:37:56,187 DEBUG MyLogger DEBUG

ファイルの中身

[logging2-test.py:21] 2008-05-26 23:40:24,765 CRITICAL MyLogger CRITICAL
[logging2-test.py:22] 2008-05-26 23:40:24,780 ERROR MyLogger ERROR
[logging2-test.py:23] 2008-05-26 23:40:24,780 WARNING MyLogger WARN
[logging2-test.py:24] 2008-05-26 23:40:24,780 INFO MyLogger INFO
[logging2-test.py:25] 2008-05-26 23:40:24,780 DEBUG MyLogger DEBUG

コンソールにはデフォルト(root)ロガーとMyLoggerのロガー出力がされて、
ファイルにはMyLoggerの出力のみで設定通りにうごいてるので、完了!!

余談 logging.basicConfig()にはまる

logggingで遊んでいて少しはまったことを暴露しておく

最初 logging.basicConfig()をつかって、マイロガーも設定するするものだと思ってた。
でも、どんなやり方やっても、rootにしかでない。。
なんでだろ。。。とマニュアル調べてもわからん。。
そこで、最後の手段はソースコード探索。。

PYTHONPATH\Lib\logging\__init__.py: 1201 - 1252

BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s"
def basicConfig(**kwargs):
    if len(root.handlers) == 0:
        filename = kwargs.get("filename")
        if filename:
            mode = kwargs.get("filemode", 'a')
            hdlr = FileHandler(filename, mode)
        else:
            stream = kwargs.get("stream")
            hdlr = StreamHandler(stream)
        fs = kwargs.get("format", BASIC_FORMAT)
        dfs = kwargs.get("datefmt", None)
        fmt = Formatter(fs, dfs)
        hdlr.setFormatter(fmt)
        root.addHandler(hdlr)
        level = kwargs.get("level")
        if level:
            root.setLevel(level)


でたーーーーー!!!
root.addHandler(hdlr) ってなってるーーーーーーっっw

そらあかんわw