python - Python 的多线程/日志记录模块的问题

标签 python opencv logging multiprocessing

我有一个并发运行的程序,我想在其中为每个子进程创建一个日志。我将首先描述我的设置,然后描述我面临的问题。这是我的主要模块:

mp_handler.py:

import logging
import multiprocessing as mp

def mp_handler(target, args_list):

    # configure logs
    for args in args_list: 
        logger_id = args[0] # first arg suffices to id a process, in my case
        logger = logging.getLogger(logger_id)
        handler = logging.FileHandler(logger_id + '.log')
        logger.setLevel(logging.INFO)
        logger.addHandler(handler)

    mp.set_start_method('spawn') # bug fix, see below        

    # build each process
    for args in args_list:
        p = mp.Process(target = target, args = args)
        p.start()

mp_worker.py:

import logging
from deco_module import deco
from my_module import function_with_open_cv

@deco
def mp_worker(args):
    logger_id = arg[0]
    logger = logging.getLogger(logger_id)

    log.info("Information about process %s" % log_id)         

    # do a lot of stuff with openCV3 
    function_with_open_cv(args)       # also logs to this child's log file

deco_module.py:这个模块做一些异常处理,我不知道为什么它会干扰,但我想我会包括它以防万一。

from functools import wraps
import logging

def deco(function):

    @wraps(function)
    def wrapper(*args):
        logger_id = *args[0]
        logger = logging.getLogger(logger_id)
        try:
            function(*args)
        except: 
            logger.info('a message in case the child fails.')

    return wrapper

现在,谈谈我的问题。我收到了这篇文章中描述的错误:https://github.com/opencv/opencv/issues/5150 .因此,我在 mp_handler() 中编写了 mp.set_start_method('spawn') 行。

然而,在调试之后,我发现该行导致 logger = logging.getLogger(logger_id)mp_worker() 创建一个新的记录器,而不是获取在父级中创建的那个,即 mp_handler()。我能够通过在父模块和子模块中打印 hex(id(logger)) 来看到这一点,并看到内存中的位置不同。事实上,正如我所说,编写 mp.set_start_method('fork') 避免了这个问题(这对我来说非常粗略,因为我的理解是 spawn 将为记录器创建一个新空间)。

主要问题:所以,问题是,为了 OpenCV,我需要将 start 方法设置为“spawn”,但需要将其关闭以便模块之间进行日志通信,我该如何解决这个问题(即为了让 mp_worker 识别其正确的 logger_id 以便登录到正确的文件)?作为良好实践的一部分,我希望将所有日志记录配置保留在子模块和子模块之外。

次要问题:假设我忽略了我需要 OpenCV 并将方法设置为“fork”的事实。在这种情况下,我注意到 function_with_open_cv() 函数中的任何 logging.info() 语句都不会进入日志!那么,假设您的建议确实涉及将其设置为 fork ,那么这里的工作是什么?编辑:固定!这也是由 OpenCV 引起的。所以问题仍然存在...我如何使用生成过程而不丢失我的记录器 ID?

非常感谢!

最佳答案

您不应在进程生成之前配置日志记录,而应在生成之后配置。参见 the documentation有关如何正确执行此操作的示例。这适用于 Python 3,但如果你需要在 Python 2 下运行它,你可以使用 logutils package ,它提供了 QueueListenerQueueHandler 类。

日志记录手册包含更多与使用多处理进行日志记录相关的示例代码。

关于python - Python 的多线程/日志记录模块的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46822226/

相关文章:

python - 如何将视频脚本保存到文本文件?

python - Photologue 不支持的操作 ('fileno' ,)

iphone - OpenCV基础教程

python - OpenCV VideoWriter 输出为空

git - 使 git log 产生命令输出 'inline'

java - 使用 Log4j 找不到记录器的附加程序

python - ICMP数据包嗅探未接收到任何数据(Black Hat Python书)

python - 获取调用事件的对象

c++ - 从实感相机中提取深度帧?

java - 尽管 isDebugEnabled 为真,但 log4j 调试消息未显示在控制台中