我正在尝试使用RotatingFileHandler
处理程序来管理Windows下运行的Python项目的可能很长的日志文件。我发现,使用IDLE解释器(在Windows PC上)运行时,日志文件旋转可以正常运行,但是从Windows命令提示符运行时,日志文件旋转会失败,并出现WindowsError异常。
下面是显示问题的示例代码-
import logging, logging.handlers
import datetime
import time
mainlogfile = 'fred.log'
logging_level = logging.DEBUG
logging_rotate_time = datetime.timedelta(minutes=1)
logger = logging.getLogger('Main_Logger')
logger.setLevel(logging.DEBUG)
handler = logging.handlers.RotatingFileHandler(mainlogfile, backupCount=7)
handler.setLevel(logging_level)
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
next_rotate = datetime.datetime.now() + logging_rotate_time
while True:
time.sleep(5)
logger.info('Tick ')
n = datetime.datetime.now()
if n>next_rotate:
logger.info('Rotating logfile')
handler.doRollover()
logger.info('Succesfully rotated logfile')
next_rotate = next_rotate + logging_rotate_time
logger.info('Next logfile rotate at '+ str(next_rotate))
当我在IDLE解释器中运行此命令时,它工作正常,并且日志文件fred.log
每分钟旋转一次,生成fred.log.1, fred.log.2
等,其内容为-
2018-12-10 12:24:40,269 INFO Succesfully rotated logfile
2018-12-10 12:24:40,269 INFO Next logfile rotate at 2018-12-10 12:25:40.182000
2018-12-10 12:24:45,269 INFO Tick
2018-12-10 12:24:50,269 INFO Tick
2018-12-10 12:24:55,269 INFO Tick
2018-12-10 12:25:00,267 INFO Tick
2018-12-10 12:25:05,267 INFO Tick
2018-12-10 12:25:10,266 INFO Tick
2018-12-10 12:25:15,266 INFO Tick
2018-12-10 12:25:20,266 INFO Tick
2018-12-10 12:25:25,266 INFO Tick
2018-12-10 12:25:30,265 INFO Tick
2018-12-10 12:25:35,265 INFO Tick
2018-12-10 12:25:40,263 INFO Tick
2018-12-10 12:25:40,263 INFO Rotating logfile
但是,在命令提示符下运行时,它在第一次旋转尝试时失败-
C:\> python try10.py
Traceback (most recent call last):
File "try10.py", line 29, in <module>
handler.doRollover()
File "C:\Python27\lib\logging\handlers.py", line 142, in doRollover
os.rename(self.baseFilename, dfn)
WindowsError: [Error 32] The process cannot access the file because it is being used by another process
我已经搜索并发现在Windows下尝试关闭或重命名另一个Python进程正在使用的日志文件时存在 问题,但是我看不到这与我的简单操作有何关系例。我尝试在handler.flush()
之前调用handler.close()
和handler.doRollover()
,但这并没有改变行为。
我的问题是-
答案 0 :(得分:0)
查看doRollover()
模块中logging.handlers
方法的代码,可以看出,当doRollover
尝试重命名日志文件{{ 1}}到fred.log
,使用fred.log.1
。尝试像这样重命名打开的文件将导致Windows下的异常,尽管在os.rename()
方法中,打开的日志文件应已关闭。由于我的程序在Windows控制台中总是失败,因此日志文件似乎没有正确关闭。在IDLE解释器中,似乎文件i / o的完成与控制台不同(通过the documentation中所述的套接字),因此也许这是允许代码在此处运行的原因。
考虑到为了允许doRollover()
重命名日志文件,必须首先关闭它,我发现可以通过在进行过渡时从记录器中临时删除处理程序来强制执行此操作-像这样-< / p>
doRollover()
使用这些mod,代码可以正常工作,并且日志文件while True:
time.sleep(5)
logger.info('Tick ')
n = datetime.datetime.now()
if n>next_rotate:
logger.info('Rotating logfile')
logger.removeHandler(handler)
handler.doRollover()
logger.addHandler(handler)
logger.info('Succesfully rotated logfile')
next_rotate = next_rotate + logging_rotate_time
logger.info('Next logfile rotate at '+ str(next_rotate))
每分钟旋转一次,按预期产生fred.log
,fred.log.1
等