python 3 : Using a multiprocessing queue for logging

标签 python logging python-3.x queue multiprocessing

我最近接受了一项挑战,即在我们的软件中进行多处理。我想要一个主进程来生成子进程,并且我需要某种方式将日志信息发送回主进程。这主要是因为我们使用的模块将警告和错误消息写入日志记录对象,我们希望这些消息出现在 gui 中,该 gui 在主进程中运行。

显而易见的方法是编写一个带有 write() 方法的小类,将 put() 放入队列,然后在日志流处理程序中使用此类。然后主进程将从该队列中获取()以将文本发送到图形用户界面。但这似乎行不通,我也不知道为什么

我写了一些示例代码来演示这个问题。它使用一个日志记录对象在子进程中写入一个队列,然后主进程尝试从队列中读取,但失败了。谁能帮我弄清楚这是怎么回事?

import time, multiprocessing, queue, logging

class FileLikeQueue:
    """A file-like object that writes to a queue"""
    def __init__(self, q):
        self.q = q
    def write(self, t):
        self.q.put(t)
    def flush(self):
        pass


def func(q):
    """This function just writes the time every second for five 
    seconds and then returns. The time is sent to the queue and 
    to a logging object"""

    stream = FileLikeQueue(q)

    log = logging.getLogger()
    infohandler = logging.StreamHandler(stream)
    infohandler.setLevel(logging.INFO)
    infoformatter = logging.Formatter("%(message)s")
    infohandler.setFormatter(infoformatter)
    log.addHandler(infohandler)

    t1 = time.time()
    while time.time() - t1 < 5: #run for five seconds
        log.info('Logging: ' + str(time.time()))
        q.put('Put: %s' % str(time.time()))
        time.sleep(1)



def main():
    q = multiprocessing.Queue()
    p = multiprocessing.Process(target=func, args=(q,))
    p.start()

    #read the queue until it is empty
    while True:
        try:
            t = q.get()
        except queue.Empty:
            break
        print(t)


if __name__ == '__main__':
    main()

我希望输出是:

Logging: 1333629221.01
Put: 1333629221.01
Logging: 1333629222.02
Put: 1333629222.02
Logging: 1333629223.02
Put: 1333629223.02
Logging: 1333629224.02
Put: 1333629224.02
Logging: 1333629225.02
Put: 1333629225.02

但我得到的是:

Put: 1333629221.01
Put: 1333629222.02
Put: 1333629223.02
Put: 1333629224.02
Put: 1333629225.02

因此 func() 中的 put() 操作有效,但日志记录无效。为什么?

谢谢。

最佳答案

您的问题出在日志记录模块的配置上:

您需要调用 log.setLevel(logging.INFO)。默认日志级别为 WARNING,因此您的日志无效。

您确实在处理程序对象上调用了 setLevel,但是记录的消息永远不会到达处理程序,因为它们被记录器过滤了。无需对处理程序本身调用 setLevel,因为它默认处理所有消息。

关于 python 3 : Using a multiprocessing queue for logging,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10028910/

相关文章:

python - 用递归计算大 O 符号

python - Django ModelChoiceField 初始数据不适用于 ForeignKey

python - 打印出一个 numpy 数组,其中包含 BMI 低于 21 的所有玩家的 BMI

java - 杀死刚刚运行的Linux进程

java - 特定文件的 Log4J 特定级别 - 附加程序

python - 有没有以下问题的解决方案

Python Regex - 匹配一个字符而不消耗它

java - 套接字在将 json 对象从 Java 传输到 Python 时被阻塞

Python RotatingFileHandler 未写入 FileHandler 写入的所有结果

python - Django 跨 View 获取上下文数据