Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python中使用多进程记录到一个文件_Python_Python 3.x_Python 2.7_Logging_Multiprocessing - Fatal编程技术网

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

在python中使用多进程记录到一个文件,python,python-3.x,python-2.7,logging,multiprocessing,Python,Python 3.x,Python 2.7,Logging,Multiprocessing,我正在尝试使用QueueHandler在多个进程之间设置日志记录。我在多次打印的日志文件中看到相同的日志。将此用作模板() 编辑 多处理文件: import logging from logging.handlers import RotatingFileHandler, QueueHandler from multiprocessing import Process from queue import Empty class MultiProcessQueueLoggingListner

我正在尝试使用QueueHandler在多个进程之间设置日志记录。我在多次打印的日志文件中看到相同的日志。将此用作模板()

编辑

多处理文件:

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)
测试文件:

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文件包含同一条目的多行。程序现在停止运行,不无限期运行,但仍能看到多行

    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,以排除附加到现有日志文件的可能性,但仍然可以看到多个日志


谢谢

您的问题是因为您正在检查一个
None
来打破循环,但这永远不会发生,因为
QueueHandler
总是将
LogRecord
写入队列,而不是
None
。如果要将
None
写入队列,则需要直接写入,而不是执行
po.logger.info(None)
。例如,将队列存储为
MulitProcessQueueLogger
实例的名为
queue
的属性,然后在
worker()中执行
po.queue.put(None)
,我意识到这不是一个“螺母和螺栓”答案,但如果实际上主要是为了实现多进程、相同的日志文件记录,有人可能比找到一个有效的现成解决方案更糟糕:就我所知,这似乎是一个成熟的项目,而且似乎工作得很好。我只需更改logging.conf文件中的一行即可实现此目标


毫无疑问,如果有人感兴趣,可以检查那里的源代码,查看他们使用的“螺母和螺栓”。

我添加了您提到的更改,现在我看到它停止了,但仍然看到同一条目的多行代码。我把处理程序搞乱了吗?@Greg Brown这是因为你还必须在新进程中而不是在父进程中初始化记录器。您的日志记录程序继承了QueueHandler,因此他在处理日志记录时会将其重新排入队列。@Darkonaut我将日志记录程序移到了进程中,而不是主进程中,但仍能看到重复的日志条目。我遗漏了什么吗?@Greg Brown
\uuuuu init\uuuu
在父级中运行,您必须将记录器的配置重新定位到
run
。制作一个
\u init\u logging
方法,并从
run
@Darkonaut调用它,进行了更改,现在可以工作了,谢谢。