1. 问题的描述
当在父进程打开日志句柄时,再启动一个子进程后,从资源监视器中,搜索日志文件,会看到父进程,和子进程同时获得了这个日志的句柄。2. 导致的问题
当出现上述的问题的时候,会导致日志滚动时,发生错误。 从logging/handlers.py源码121行的doRollover 方法,看出会将日志的名称后加上".1"(源码第136行)。从这里就可以很清楚知道错误的原因。因为两个进程分别获取到了一个文件的句柄,当改名字就会报错3. 解决的方法
解决的方法取决于你是如何启动子进程的。3.1 通过subprocess.Popen起的进程
如果你没有定义stdin,stdout,stderr的管道,你可以使用close_fds=True来拒接继承父类的句柄。 倘若,你已经定义管道,则会报错。3.2 更通用的解决办法
class BaseRotatingHandler(logging.FileHandler):
"""
Base class for handlers that rotate log files at a certain point.
Not meant to be instantiated directly. Instead, use RotatingFileHandler
or TimedRotatingFileHandler.
"""
def __init__(self, filename, mode, encoding=None, delay=0):
"""
Use the specified filename for streamed logging
"""
if codecs is None:
encoding = None
logging.FileHandler.__init__(self, filename, mode, encoding, delay)
self.mode = mode
self.encoding = encoding
def emit(self, record):
"""
Emit a record.
Output the record to the file, catering for rollover as described
in doRollover().
"""
try:
if self.shouldRollover(record):
self.doRollover()
logging.FileHandler.emit(self, record)
except (KeyboardInterrupt, SystemExit):
raise
except:
self.handleError(record)
finally:#以下是我修改的代码
self.stream.close()
self.stream = None
上面是修改后的源码,logging/headers.py:52行的emit方法