首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在python中使用多个进程记录一个文件

在python中使用多个进程记录一个文件
EN

Stack Overflow用户
提问于 2018-09-25 17:35:14
回答 2查看 1.7K关注 0票数 3

我正在尝试使用QueueHandler在多个进程之间设置日志记录。我在多次打印的日志文件中看到相同的日志。使用此模板(https://docs.python.org/3/howto/logging-cookbook.html#logging-to-a-single-file-from-multiple-processes)

编辑

多处理文件:

代码语言:javascript
复制
import logging
from logging.handlers   import RotatingFileHandler, QueueHandler
from multiprocessing import Process
from queue import Empty

class MultiProcessQueueLoggingListner(Process):
    def __init__(self, name, queue):
        super().__init__()
        self.name = name
        self.queue = queue
        self.logger = logging.getLogger(name)
        self.file_handler = RotatingFileHandler(name, maxBytes=536870912, backupCount=2)
        self.formatter = logging.Formatter('%(asctime)s %(processName)-10s %(name)s %(levelname)-8s %(message)s')
        self.file_handler.setFormatter(self.formatter)
        self.logger.addHandler(self.file_handler)

    def run(self):
        while True:
            try:
                record = self.queue.get()
                if record is None:
                    break
                self.logger.handle(record)
            except Exception:
                import sys, traceback
                print('Whoops! Problem:', file=sys.stderr)
                traceback.print_exc(file=sys.stderr)


class MulitProcessQueueLogger(object):
def __init__(self, name, queue):
    self.name = name
    self.queue = queue
    self.queue_handler = QueueHandler(queue)
    self.logger = logging.getLogger(name)
    self.logger.addHandler(self.queue_handler)
    self.logger.setLevel(logging.DEBUG)

测试文件:

代码语言:javascript
复制
import multi_process_logging
import multiprocessing
from time import sleep


def worker(po):
    name = multiprocessing.current_process().name
    po = multi_process_logging.MulitProcessQueueLogger('test.log', q)
    print("In worker")
    for i in range(10):
        po.logger.info(f"Logging from {name} line {i}")
    po.queue.put(None)

def main():
    q = multiprocessing.Queue()
    lp = multi_process_logging.MultiProcessQueueLoggingListner('test.log', q)
    lp.start()
    p = multiprocessing.Process(target=worker, args=(q,))
    p.start()
    p.join()
    lp.join()



if __name__ == '__main__':
    main()

我看到的问题是,test.log文件包含同一条目的多行。程序现在停止,不会无限期地运行,但仍会看到多行

代码语言:javascript
复制
    cat test.log | grep 'line 0'
2018-09-26 16:32:40,117 Process-2  test.log INFO     Logging from Process-2 line 0
2018-09-26 16:32:40,117 Process-2  test.log INFO     Logging from Process-2 line 0
2018-09-26 16:32:40,117 Process-2  test.log INFO     Logging from Process-2 line 0
2018-09-26 16:32:40,117 Process-2  test.log INFO     Logging from Process-2 line 0
2018-09-26 16:32:50,318 Process-2  test.log INFO     Logging from Process-2 line 0
2018-09-26 16:32:50,318 Process-2  test.log INFO     Logging from Process-2 line 0
2018-09-26 16:32:50,318 Process-2  test.log INFO     Logging from Process-2 line 0
2018-09-26 16:32:50,318 Process-2  test.log INFO     Logging from Process-2 line 0

我在运行之前删除了test.log,以排除附加到现有日志文件上的可能性,但仍然可以看到多个日志。

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-09-26 19:54:45

您的问题是由这样一个事实引起的:您正在检查是否有一个None脱离循环,但这永远不会发生,因为QueueHandler总是将LogRecord写入队列,而不是None。如果要将None写入队列,则需要直接写入它,而不是执行po.logger.info(None)。例如,将队列存储为名为queueMulitProcessQueueLogger实例的属性,然后在worker()中执行po.queue.put(None)

票数 1
EN

Stack Overflow用户

发布于 2021-04-13 12:29:25

我意识到这不是一个“具体问题”的答案,但如果其意图实际上主要是实现多进程、相同日志文件的日志记录,一个人可能会比找到一个有效的现成解决方案更糟糕:并发日志处理程序似乎是一个成熟的项目,就我所知,它似乎运行得很好。我只需更改logging.conf文件中的一行即可达到目标。

毫无疑问,如果有兴趣的话,我们可以查看源代码,查看它们使用过的“螺母和螺栓”。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52503870

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档