最近,我发现我的应用程序生成的日志记录少于预期。经过一些实验,我发现问题出现在RotatingFileHandler和多处理中。
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
我做错了什么?
答案 0 :(得分:2)
因为它是well explained,
虽然日志记录是线程安全的,并且支持在单个进程中从多个线程记录到单个文件,但不支持从多个进程记录到单个文件
简而言之,RotatingFileHandler
只关闭并从一个进程中删除文件,然后打开一个新文件。但是其他进程不知道新的文件描述符,并且看到之前的文件描述符已经关闭。只有设法旋转文件的进程才会继续记录。
在类似问题的my answer中,我建议使用logrotate
守护程序将文件旋转到这些进程之外。它不关闭文件描述符,只是截断文件。因此文件保持不变,其他进程可以继续记录。