tdi*_*ihp 10 python logging multiprocessing
一段时间以来,我一直在努力处理多处理日志,原因有很多.
我的一个原因是,为什么另一个get_logger.
当然我已经看到了这个问题,似乎multiprocessing.get_logger返回的记录器做了一些"进程共享锁"魔术,使日志处理顺利进行.
所以,今天我研究了Python 2.7的多处理代码(/multiprocessing/util.py),发现这个记录器只是一个普通的logging.Logger,并且几乎没有任何魔法.
这是Python文档中的描述,就在get_logger函数之前:
可以使用一些日志记录支持.但请注意,日志记录包不使用进程共享锁,因此可能(取决于处理程序类型)来自不同进程的消息混淆.
因此,当您使用错误的日志记录处理程序时,即使是get_logger记录器也可能出错?我用过一个程序使用get_logger来记录一段时间.它将日志打印到StreamHandler并且(似乎)永远不会混淆.
现在我的理论是:
这是问题:
我的理论是对的吗?
如何/为什么/何时使用此get_logger?
是的,我相信 multiprocessing.get_logger() 不做进程共享锁是对的 - 正如你所说,文档甚至说明了这一点。尽管获得了所有赞成票,但您链接到的问题似乎在说明它确实存在缺陷(为了使它具有怀疑的好处,它是十多年前写的 - 所以也许在某一时刻就是这种情况)。
那么为什么 multiprocessing.get_logger() 存在呢?该文件说,它:
返回多处理使用的记录器。如有必要,将创建一个新的。
首次创建时,记录器具有级别 logging.NOTSET 并且没有默认处理程序。默认情况下,发送到此记录器的消息不会传播到根记录器。
即默认情况下,多处理模块不会产生任何日志输出,因为其记录器的日志级别设置为 NOTSET,因此不会产生任何日志消息。
如果您怀疑您的代码存在多处理问题,那么缺少日志输出将无助于调试,这就是 multiprocessing.get_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
Run Code Online (Sandbox Code Playgroud)
也就是说,为了方便起见,您实际上可能想使用 multiprocessing.log_to_stderr() 代替 - 根据文档:
此函数执行对 get_logger() 的调用,但除了返回由 get_logger 创建的记录器之外,它还添加了一个使用格式将输出发送到 sys.stderr 的处理程序
'[%(levelname)s/%(processName)s] %(message)s'
即它使您无需自己设置如此多的日志记录配置,而您只需使用以下命令即可开始调试多处理问题:
logger = multiprocessing.log_to_stderr()
logger.setLevel(logging.INFO)
# now run your multiprocessing code
Run Code Online (Sandbox Code Playgroud)
重申一下,这只是一个正在配置和使用的普通模块记录器,即它没有什么特别的或过程安全的。它只是让您看到多处理模块本身内部发生了什么。