背景
最近在对数据进行预处理,由于数据量较大,处理步骤较多,所以使用日志对处理中间环节进行记录,方便查错定位与断点续传。Python自带了好用的日志库logging,具体的logging教程就不再赘述,具体可以参见官方手册与这篇博客,这里主要记录一下我在使用过程中遇到的问题。如前面所说,由于处理的数据量比较大,所以除了使用日志以外,我还考虑使用多进程来讲任务并行化,提高处理效率(虽然只是在数据库上加了索引就极大的提升了效率,导致最终没有用上并行化),在这个过程中遇到了一些问题,就记录在这里。
日志部分
问题
在使用多进程的时候,为了方便查错,避免所有的信息都记录在一个日志文件中,我决定每个子进程都有自己的日志文件,即每个子进程有自己的Logger,每个Logger都对应着唯一的日志文件(根据进程的id命名)。但是,在实际实践过程中,我发现子进程的日志文件中,通常会出现重复的日志记录,问题描述可以参照这篇博客,以下是复现该问题是使用的样例代码:
class BasicLogger(object):
def __init__(self, _name:str, _level=logging.DEBUG):
self.logger = logging.getLogger(name=_name)
self.logger.setLevel(_level)
# 控制台输出的Handler
streamHandler = logging.StreamHandler()
streamHandler.setLevel(logging.CRITICAL)
streamHandler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(process)d - %(message)s"))
# 文件输出的Handler
logPath = 'logs'
if not os.path.exists(logPath):
os.makedirs(logPath)
fileHandler = logging.FileHandler(filename=os.path.join(logPath, "%s.log"%_name), encoding='utf-8')
fileHandler.setLevel(logging.DEBUG)
fileHandler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(process)d - %(message)s"))
self.logger.addHandler(streamHandler)
self.logger.addHandler(fileHandler)
def info(self, msg):
self.logger.info(msg)
def debug(self, msg):
self.logger.debug(msg)
def warn(self, msg):
self.