Windows下的Python记录器`RotatingFileHandler`失败

时间:2018-12-10 18:26:35

标签: python windows

我正在尝试使用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(),但这并没有改变行为。

我的问题是-

  • 为什么在命令提示符下运行但不在空闲状态下引发异常?
  • 我是否可以对代码进行任何更改,以使其能够在Windows命令提示符下运行

1 个答案:

答案 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.logfred.log.1