[英]Python logger `RotatingFileHandler` failing under Windows
I am trying to use the RotatingFileHandler
handler to manage potentially long logfiles for a Python project running under Windows. 我正在尝试使用RotatingFileHandler
处理程序来管理Windows下运行的Python项目的可能很长的日志文件。 I have found that the log file rotation works fine when run using the IDLE interpreter (on a Windows PC) but fails with a WindowsError exception when run from the Windows command prompt. 我发现,使用IDLE解释器(在Windows PC上)运行时,日志文件旋转可以正常运行,但是从Windows命令提示符运行时,日志文件旋转会失败,并出现WindowsError异常。
Here is an example code that shows the problem - 这是显示问题的示例代码-
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))
When I run this in the IDLE interpreter, it works fine and the log file fred.log
is rotated every minute producing fred.log.1, fred.log.2
etc. with contents such as - 当我在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
However, when run in a command prompt it fails on the first rotate attempt - 但是,在命令提示符下运行时,第一次尝试旋转失败-
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
I have searched and found that there are problems under Windows when trying to close or rename log files that are in use by another Python process but I can't see how that is relevant to my simple example. 我已搜查,发现试图关闭或重命名由另一个Python过程中使用的日志文件时有 Windows下的问题,但我看不出这是有关我的简单的例子。 I have tried calling handler.flush()
and handler.close()
before handler.doRollover()
but this did not change the behavior. 我试过在handler.doRollover()
之前调用handler.flush()
和handler.close()
,但这并没有改变行为。
My questions are - 我的问题是-
Looking at the code of the doRollover()
method in the logging.handlers
module, it can be seen that the exception above is being raised when doRollover
tries to rename the log-file fred.log
to fred.log.1
using os.rename()
. 综观的代码doRollover()
中方法logging.handlers
模块,它可以看出,上述被引发的异常时doRollover
尝试重命名记录文件fred.log
到fred.log.1
使用os.rename()
。 Trying to rename an open file like this will cause the exception under Windows, although earlier in the doRollover()
method the open logfile should have been closed. 尝试像这样重命名打开的文件将导致Windows下的异常,尽管在doRollover()
方法的早期,打开的日志文件应已关闭。 Since my program as stands always fails in Windows console it looks like the logfile is not being properly closed. 由于我的程序在Windows控制台中总是失败,因此日志文件似乎没有正确关闭。 In the IDLE interpreter, it seems that file i/o is done differently than the console (via sockets as described in the documentation ) so maybe that this is what allows the code to run there. 在IDLE解释器中,似乎文件I / O的完成方式不同于控制台(通过文档中所述的套接字),因此也许这是允许代码在此处运行的原因。
Given that in order to allow doRollover()
to rename the logfile, it has to be closed first and I discovered that this can be forced by temporarily removing the handler from the logger while doing the rollover - like this - 鉴于为了允许doRollover()
重命名日志文件,必须首先将其关闭,我发现可以通过在进行过渡时从记录器中临时删除处理程序来强制执行此操作-像这样-
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))
With these mods the code works fine and the log file fred.log
is rotated every minute producing fred.log.1
, fred.log.2
etc. as expected 使用这些mod,代码可以正常工作,并且日志文件fred.log
每分钟旋转一次, fred.log.2
按预期生成fred.log.1
, fred.log.2
等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.