Вход с использованием нескольких процессов в один файл в Python - PullRequest
0 голосов
/ 25 сентября 2018

Я пытаюсь настроить ведение журнала между несколькими процессами, используя 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()

Проблема Iвидно, что файл 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 перед выполнением правиладобавьте его в существующий файл журнала, но при этом увидите несколько журналов.

Спасибо

1 Ответ

0 голосов
/ 26 сентября 2018

Ваша проблема вызвана тем, что вы проверяете, что None выходит из цикла, но это никогда не произойдет, потому что QueueHandler всегда записывает LogRecord в очередь, а не * 1004.*.Если вы хотите записать None в очередь, вам нужно записать это напрямую, а не делать po.logger.info(None).Например, сохраните очередь как атрибут с именем queue вашего экземпляра MulitProcessQueueLogger, а затем выполните po.queue.put(None) в worker().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...