为什么在多个过程中使用Python记录旋转filehandler会丢失记录



最近,我意识到我的应用程序生成的日志记录比我预期的要少。经过一些实验,我发现问题在于旋转和多处理。

import logging
from logging import handlers
from multiprocessing import Pool
import os

log_file_name = 'log.txt'
def make_logger():
    logger = logging.getLogger('my_logger')
    logger.setLevel(logging.INFO)
    current_handler_names = {handler.name for handler in logger.handlers}
    handler_name = 'my_handler'
    if handler_name in current_handler_names:
        return logger
    handler = handlers.RotatingFileHandler(
        log_file_name, maxBytes=10 * 2 ** 10, backupCount=0)
    handler.setLevel(logging.INFO)
    handler.set_name(handler_name)
    logger.addHandler(handler)
    return logger

def f(x):
    logger = make_logger()
    logger.info('hey %s' % x)

if os.path.exists(log_file_name):
    os.unlink(log_file_name)
p = Pool(processes=30)
N = 1000
p.map(f, range(N))
with open(log_file_name, 'r') as f:
    print 'expected: %s, real: %s' % (N, f.read().count('hey'))

输出:

$ python main.py
expected: 1000, real: 943

我做错了什么?

,这是很好的解释,

虽然记录是线程安全的,并且支持单个过程中多个线程的单个文件记录,但不支持从多个进程中登录到单个文件

用几句话,RotatingFileHandler只需关闭并从一个进程中删除文件,然后打开一个新文件。但是其他过程不了解新文件描述符,并发现以前已经关闭了。只有设法旋转文件的过程首先继续记录。

在回答我建议使用logrotate守护程序将文件旋转这些过程的类似问题的回答中。它不会关闭文件描述符,而只是 truncates 文件。因此,文件保持不变,其他过程可以继续记录。

相关内容

  • 没有找到相关文章

最新更新