一段时间以来,由于许多原因,我一直在与多处理日志进行斗争。
我的理由之一是,为什么是另一个get_logger。
当然,我已经看到了这个问题,而且multiprocessing.get_logger返回的记录器似乎具有一些“进程共享锁”的魔力,以使日志处理变得平滑。
因此,今天我研究了Python2.7 (/ multiprocessing /util.py)的多处理代码,发现这个记录器只是一个普通的logging.Logger,几乎没有任何魔力。
下面是Python文档中的描述,就在get_logger函数之前:
有一些对日志记录的支持。但是,请注意,日志程序包不使用进程共享锁,因此可以(取决于处理程序类型)将来自不同进程的消息混在一起。
因此,当您使用错误的日志处理程序时,即使是get_logger记录器也可能出错?一段时间以来,我使用了一个使用get_logger的程序进行日志记录。它将日志打印到StreamHandler,而且(似乎)从不混淆。
现在我的理论是:
以下是一个问题:
我的理论对吗?
如何/为什么/什么时候使用这个get_logger?
发布于 2020-05-28 22:15:55
是的,我相信您是对的,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也就是说,为了方便起见,您可能实际上希望使用multiprocessing.log_to_stderr() --如文档所示
该函数执行对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不过,重申一下,这只是一个正在配置和使用的普通模块记录器,也就是说,它没有什么特殊的或过程安全的。它只让您看到多处理模块本身发生了什么。
发布于 2012-11-23 11:33:38
这个答案并不是专门关于get_logger的,但是也许您可以使用这个职位中建议的方法?请注意,QueueHandler/QueueListener类可以通过logutils包(也是可用的论PyPI )提供给早期版本。
https://stackoverflow.com/questions/13522177
复制相似问题