Python的RotatingFileHandler的Bug
最近有在开发自动化测试工具,刚好需要logging模块,但在使用logging模块的rotatingfilehandler时,常抛出异常。打印类似于如下异常信息:
1 lne 86, in __init__
2 rotatinghandler.dorollover()
3 file "/lib/python2.7/lib/logging/handlers.py", line 131, in dorollover
4 os.rename(self.basefilename, dfn)
5 oserror: [errno 13] permission denied
查看日志文件权限后,发现文件属性全为问号,而对其执行copy或者move命令后,文件属性恢复正常。网上有说是在多个地方调用getlogger之后导致的问题,排查发现并无其他多余模块获取了同样的logger,暂时无解。(后来发现:存在多个线程通过logging直接记录日志到日志文件,多线程同时操作一个日志文件可能导致该错误)
随后google到一篇早期讨论帖才找到办法:
1、找到logging库下的handlers.py文件,定位到rotatingfilehandler的基类的dorollover方法,修改如下代码:
1 try:
2 os.rename(self.basefilename, dfn)
3 #记得先import shutil,替换为:
4 try:
5 shutil.move(self.basefilename, dfn)
2、可能导致日志记录操作异常,如出现如下异常(异常信息来自网络):
1 traceback (most recent call last):
2 file "c:\python24\lib\logging\handlers.py", line 72, in emit
3 self.dorollover()
4 file "c:\python24\lib\logging\handlers.py", line 141, in dorollover
5 self.handleerror(record)
6 nameerror: global name 'record' is not defined
请尝试如下修改:
1 if self.shouldrollover(record):
2 self.dorollover()
3 #修改为:
4 if self.shouldrollover(record):
5 self.dorollover(record)
3、按ctrl+c退出程序时,可能将打印如下异常:
复制代码
1 error in atexit._run_exitfuncs:
2 traceback (most recent call last):
3 file "c:\python24\lib\atexit.py", line 24, in _run_exitfuncs
4 func(*targs, **kargs)
5 file "c:\python24\lib\logging\__init__.py", line 1333, in shutdown
6 h.close()
7 file "c:\python24\lib\logging\__init__.py", line 772, in close
8 streamhandler.close(self)
9 file "c:\python24\lib\logging\__init__.py", line 674, in close
10 del _handlers[self]
11 keyerror: <logging.handlers.rotatingfilehandler instance at 0x01e098a0>
12 error in sys.exitfunc:
13 traceback (most recent call last):
14 file "c:\python24\lib\atexit.py", line 24, in _run_exitfuncs
15 func(*targs, **kargs)
16 file "c:\python24\lib\logging\__init__.py", line 1333, in shutdown
17 h.close()
18 file "c:\python24\lib\logging\__init__.py", line 772, in close
19 streamhandler.close(self)
20 file "c:\python24\lib\logging\__init__.py", line 674, in close
21 del _handlers[self]
22 keyerror: <logging.handlers.rotatingfilehandler instance at 0x01e098a0>
复制代码
请尝试如下修改:
复制代码
1 _acquirelock()
2 try: #unlikely to raise an exception, but you never know...
3 del _handlers[self]
4 _handlerlist.remove(self)
5 finally:
6 _releaselock()
7
8 #修改为:
9 _acquirelock()
10 try: #unlikely to raise an exception, but you never know...
11 #del _handlers[self]
12 if ( _handlers.has_key(self) ): del _handlers[self]
13 #if ( self in _handlerlist ): _handlerlist.remove(self)
14 _handlerlist.remove(self)
15 finally:
16 _releaselock()