首页 > 解决方案 > 从多个进程记录到单个文件:为什么有效?

问题描述

以下是Python Logging Cookbook的摘录:

虽然日志记录是线程安全的,并且支持在单个进程中从多个线程记录到单个文件,但不支持从多个进程记录到单个文件,因为没有标准方法可以跨多个进程序列化对单个文件的访问Python 中的进程。

但是,我制作了一个简单的程序,它有多个进程记录到一个文件中,我想了解它为什么工作以及我应该什么时候预计它会失败。

以下是我正在使用的模块记录器:

import os
import logging
from datetime import datetime

def get_logger(name):
    timestamp = datetime.now().strftime('%Y%m%d-%H%M')
    logging.basicConfig(filename=f'{timestamp}.log', filemode='w',
                    style='{', level=logging.DEBUG,
                    format='{asctime}\t{name}\t{levelname}\t{message}')
    return logging.getLogger(name)

这是我如何使用它在整个程序中记录信息的示例:

import time
import random
import multiprocessing

from logger import get_logger

def function_1_that_logs(i):
    for i in range(10):
        n = random.randint(0,5)
        logger.debug(f'process {i} sleeping for {n} seconds')
        time.sleep(n)

def function_2_that_logs(i):
    logger.info(f'simple log from process {i}')

if __name__ == '__main__':

    logger = get_logger(__file__)

    logger.info('started logging')

    pool1 = multiprocessing.Pool(multiprocessing.cpu_count())
    pool2 = multiprocessing.Pool(multiprocessing.cpu_count())

    for i in range(multiprocessing.cpu_count()):
        pool1.apply_async(function_1_that_logs, [i+1])
        pool2.apply_async(function_2_that_logs, [(i+1*2)])

    pool1.close()
    pool1.join()
    pool2.close()
    pool2.join()
    logger.info('finished logging')

我已经实现了一个解决方案,该解决方案将猴子补丁应用于info、和函数debug,它们只有在具有全局互斥变量授予的访问权限时才能工作。但是,我仍然想了解为什么这个简单的代码有效,即使食谱说明相反。是因为我在 Linux 上运行并且它使用创建进程,因此不需要序列化记录器对象吗?这种幼稚的解决方案在哪里会失败?warningerrorfork

编辑:

这是写入所有内容且未发生错误的输出日志。我还有一个来自实际程序运行的 35MB 日志,显然一切都很好。

标签: pythonpython-3.x

解决方案


推荐阅读