为什么日志出现无限循环?
我有以下代码:
#!/usr/bin/env python
import logging
import sys
import copy
class Wrapper:
def write(self, s):
#sys.__stdout__.write(s)
loggy = logging.getLogger('foobar')
loggy.info(s)
def blah():
logger = logging.getLogger('foobar')
logger.setLevel(logging.DEBUG)
streamhandle = logging.StreamHandler(sys.stdout)
streamhandle.setFormatter(logging.Formatter('[%(message)s]'))
logger.addHandler(streamhandle)
sys.stdout = Wrapper()
sys.stderr = Wrapper()
if __name__ == '__main__':
blah()
logger = logging.getLogger('')
#print logger.handlers
#for handler in logger.handlers:
# print handler
fooy = logging.getLogger('foobar')
#print fooy.handlers
sys.stdout.write('i love you')
logging.log(logging.DEBUG, 'i love you')
这段代码让Python陷入了一个无限递归的循环,输出结果实际上非常酷:
[Error in sys.exitfunc:
]
[INFO:foobar:Error in sys.exitfunc:
]
[INFO:foobar:INFO:foobar:Error in sys.exitfunc:
]
[INFO:foobar:INFO:foobar:INFO:foobar:Error in sys.exitfunc:
]
[INFO:foobar:INFO:foobar:INFO:foobar:INFO:foobar:Error in sys.exitfunc:
]
[INFO:foobar:INFO:foobar:INFO:foobar:INFO:foobar:INFO:foobar:Error in sys.exitfunc:
这个输出会以指数级的速度增长 :) 看起来很漂亮,但这是为什么呢?
1 个回答
6
这个无限循环发生的原因是因为你的记录器(logger)的 StreamHandler
被设置为将日志信息写入 sys.stdout
,而 sys.stdout
又被包装起来,结果又写回到刚刚发送写入信息的那个记录器。
根据你的需求,可能更好的是让 Wrapper
直接进行输出,而不是在内部使用日志记录。可以考虑这样做:
class Wrapper(object):
def write(self, s):
sys.__stdout__.write(s) # sys.__stdout__ points to the original stdout, rather
# than the redirected sys.stdout