以下是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
,warning
和error
函数的解决方案,这些函数只有在具有访问权限的情况下才能工作由全局互斥变量授予。但是,即使菜谱相反,我仍然想理解为什么这个简单的代码起作用。是因为我在Linux上运行,并且它使用fork
创建了进程,因此不需要序列化logger对象?这种天真的解决方案在哪里失败?
编辑:
这里是output log,所有内容均已写入且未发生任何错误。我还从运行的实际程序中获得了35MB的日志,显然一切正常。