Python的RotatingFileHandler的Bug


Python的库非常强大,基本能找到我们所有需要的lib。logging模块是Python中的日志记录库,借鉴了Java中的LOG4J模块的思想,能非常方便的用于记录软件执行日志。
 
最近有在开发自动化测试工具,刚好需要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()

评论关闭