我一直在努力处理多处理日志,原因很多。
我的一个原因是,为什么另一个get_logger。
当然我见过this question,似乎multiprocessing.get_logger返回的记录器做了一些“进程共享锁”魔术,使日志处理顺利进行。
所以,今天我研究了Python 2.7的多处理代码(/multiprocessing/util.py),发现这个记录器只是一个普通的logging.Logger,并且几乎没有任何魔法。
这是Python文档中的描述,就在之前 get_logger函数:
可以使用一些日志记录支持。但请注意,日志记录 包不使用进程共享锁,所以它是可能的(取决于 在处理程序类型上)来自不同进程的消息 混淆了。
因此,当您使用错误的日志记录处理程序时,即使是get_logger记录器也可能出错? 我用过一个程序使用get_logger来记录一段时间。 它将日志打印到StreamHandler并且(似乎)永远不会混淆。
现在我的理论是:
以下是问题:
我的理论是对的吗?
如何/为什么/何时使用此get_logger?
答案 0 :(得分:5)
是的,我相信multiprocessing.get_logger()不会执行进程共享锁是正确的-正如您所说,文档甚至对此进行了说明。尽管有所有的支持,但您链接到的question似乎在声明它确实存在缺陷(为了使它具有疑问的好处,它是十年前写的,所以也许有时候是这样) )。
那么为什么multiprocessing.get_logger()存在? docs说:
返回多处理使用的记录器。如有必要,将创建一个新的。
首次创建时,记录器具有级别的logging.NOTSET且没有默认处理程序。默认情况下,发送到该记录器的消息不会传播到根记录器。
即默认情况下,由于多处理模块的记录器的日志记录级别设置为NOTSET,因此不会产生任何日志输出。
如果您的代码有问题,怀疑是多处理问题,那么缺少日志输出将无助于调试,这就是multiprocessing.get_logger()的作用-它返回多处理模块本身使用的logger,以便您可以覆盖默认的日志记录配置以从中获取一些日志并查看其工作情况。
由于您询问了如何使用multiprocessing.get_logger(),因此将其命名并以通常的方式配置记录器,例如:
logger = multiprocessing.get_logger()
formatter = logging.Formatter('[%(levelname)s/%(processName)s] %(message)s')
handler = logging.StreamHandler()
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.INFO)
# now run your multiprocessing code
也就是说,为了方便起见,实际上您可能想使用multiprocessing.log_to_stderr()-根据docs:
此函数执行对get_logger()的调用,但除了返回由get_logger创建的记录器之外,它还添加了一个处理程序,该处理程序使用格式
'[%(levelname)s/%(processName)s] %(message)s'
将输出发送到sys.stderr。
即它省去了您自己设置大量日志记录配置的麻烦,而您可以使用以下方法开始调试多处理问题:
logger = multiprocessing.log_to_stderr()
logger.setLevel(logging.INFO)
# now run your multiprocessing code
不过,重申一下,这只是配置和使用的普通模块记录器,即没有什么特别的或过程安全的。它只是让您了解多处理模块本身内部发生了什么。
答案 1 :(得分:1)