我正在尝试使用QueueHandler在多个进程之间设置日志记录。我在多次打印的日志文件中看到同一条日志。将其用作模板(https://docs.python.org/3/howto/logging-cookbook.html#logging-to-a-single-file-from-multiple-processes)
编辑
多重处理文件:
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,以排除将其追加到现有日志文件中的情况,但仍然看到多个日志。
谢谢
答案 0 :(得分:1)
您的问题是由以下事实引起的:您正在检查是否None
脱离循环,但这永远不会发生,因为QueueHandler
总是将LogRecord
写入队列,切勿None
。如果要将None
写到队列中,则需要直接写,而不要写po.logger.info(None)
。例如,将队列存储为queue
实例的名为MulitProcessQueueLogger
的属性,然后在po.queue.put(None)
中执行worker()
。
答案 1 :(得分:0)
我意识到这不是一个“具体细节”的答案,但如果实际上主要是为了实现多进程、相同日志文件的日志记录,那么可能比找到一个有效的现成工具还要糟糕解决方案:concurrent-log-handler 似乎是一个成熟的项目,据我所知似乎工作得很好。我只需要更改我的 logging.conf 文件中的一行即可实现目标。
毫无疑问,如果有兴趣,可以检查那里的源代码以查看他们使用的“具体细节”。