Я использую пакет регистрации для входа из 3 модулей и нескольких процессов в одном файле журнала, у меня есть эти три модуля:
#main.py
def worker_configurer(queue):
h = logging.handlers.QueueHandler(queue)
root = logging.getLogger()
root.addHandler(h)
root.setLevel(logging.DEBUG)
def listener_configurer():
log_file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'logging.conf')
logging.config.fileConfig(log_file_path)
def listener_process(queue, configurer):
configurer()
while True:
try:
record = queue.get()
if record is None:
break
recordName = record.name
logger = logging.getLogger(recordName)
logger.handle(record)
except Exception:
traceback.print_exc(file=sys.stderr)
if __name__=='__main__':
logging_queue = Queue(-1)
listener = Process(target=listener_process,
args=(logging_queue, listener_configurer))
listener.start()
worker_configurer(logging_queue)
logger = logging.getLogger('mylogger')
logger.info('This messgae from main process')
x = 5
y = 5
summation = a.A()
summation.toyFunc(x, y)
process = b.B(logging_queue)
process.start()
Второй модуль, этот модуль просто регистрирует одно сообщение:
#a.py
logger = logging.getLogger('mylogger.a')
class A():
def toyFunc(self, x, y):
logger.info('result: {}'.format(x+y))
Третий модуль, этот модуль некоторое время отправляет сообщение и спит:
#b.py
logger = logging.getLogger('mylogger.b')
def worker_configurer(queue):
h = logging.handlers.QueueHandler(queue)
root = logging.getLogger()
root.addHandler(h)
root.setLevel(logging.DEBUG)
class B(Process):
def __init__(self, logging_queue, func=worker_configurer):
super(B, self).__init__()
self.logging_queue = logging_queue
self.func = func
def run(self):
self.func(self.logging_queue)
for i in range(10):
logger.info('hi: {}'.format(i))
time.sleep(5)
Это мой файл конфигурации:
#logging.conf
[loggers]
keys=root,mylogger
[handlers]
keys=rootHandler,myloggerHandler
[formatters]
keys=formatter1
[logger_root]
#level=WARNING
level=ERROR
handlers=rootHandler
qualname=root
[logger_mylogger]
level=DEBUG
handlers=myloggerHandler
qualname=mylogger
propagate=0
[handler_rootHandler]
class=logging.handlers.TimedRotatingFileHandler
formatter=formatter1
args=("root.log", 'D', 1, 0, )
[handler_myloggerHandler]
class=logging.handlers.TimedRotatingFileHandler
formatter=formatter1
args=("mylogger.log", 'D', 1, 0, )
[formatter_formatter1]
format=%(asctime)s ~ %(levelname)s ~ %(process)d ~ %(module)s ~ %(funcName)s ~ %(message)s ~
Это вывод:
2020-04-10 17: 28: 49,327 ~ ИНФОРМАЦИЯ ~ 21820 ~ main ~ ~ Это сообщения из основного процесса ~
2020-04-10 17: 28: 49,328 ~ ИНФОРМАЦИЯ ~ 21820 ~ a ~ toyFun c ~ результат: 10 ~
2020-04-10 17: 28: 49,340 ~ ИНФОРМАЦИЯ ~ 21886 ~ b ~ run ~ hi: 0 ~
2020- 04-10 17: 28: 49,340 ~ ИНФОРМАЦИЯ ~ 21886 ~ b ~ run ~ hi: 0 ~
2020-04-10 17: 28: 54,347 ~ INFO ~ 21886 ~ b ~ run ~ hi: 1 ~
2020-04-10 17: 28: 54,347 ~ ИНФОРМАЦИЯ ~ 21886 ~ b ~ run ~ hi: 1 ~
2020-04-10 17: 28: 59,353 ~ ИНФОРМАЦИЯ ~ 21886 ~ b ~ run ~ hi: 2 ~
2020-04-10 17: 28: 59,353 ~ ИНФОРМАЦИЯ ~ 21886 ~ b ~ run ~ hi: 2 ~
2020-04-10 17: 2 9: 04,358 ~ ИНФОРМАЦИЯ ~ 21886 ~ b ~ run ~ hi: 3 ~
2020-04-10 17: 29: 04,358 ~ INFO ~ 21886 ~ b ~ run ~ hi: 3 ~
2020-04-10 17: 29: 09,362 ~ ИНФОРМАЦИЯ ~ 21886 ~ b ~ run ~ hi: 4 ~
2020-04-10 17: 29: 09,362 ~ INFO ~ 21886 ~ b ~ run ~ hi : 4 ~
2020-04-10 17: 29: 14 362 ~ INFO ~ 21886 ~ b ~ run ~ hi: 5 ~
2020-04-10 17: 29: 14 362 ~ INFO ~ 21886 ~ b ~ run ~ hi: 5 ~
2020-04-10 17: 29: 19,368 ~ INFO ~ 21886 ~ b ~ run ~ hi: 6 ~
2020-04- 10 17: 29: 19,368 ~ ИНФОРМАЦИЯ ~ 21886 ~ b ~ run ~ hi: 6 ~
2020-04-10 17: 29: 24,373 ~ INFO ~ 21886 ~ b ~ run ~ hi: 7 ~
2020-04-10 17: 29: 24 373 ~ ИНФОРМАЦИЯ ~ 21886 ~ b ~ run ~ hi: 7 ~
2020-04-10 17: 29: 29 379 ~ ИНФО ~ 21886 ~ b ~ run ~ hi: 8 ~
2020-04-10 17: 29: 29,379 ~ INFO ~ 21886 ~ b ~ run ~ hi ~ hi: 8 ~
2020-04-10 17:29: 34 382 ~ ИНФОРМАЦИЯ ~ 21886 ~ b ~ run ~ hi: 9 ~
2020-04-10 17: 29: 34,382 ~ INFO ~ 21886 ~ b ~ run ~ hi: 9 ~
Как видите , сообщения дублируются от многопроцессорного класса, как решить эту проблему? просто чтобы быть понятным, мне нужно вызвать A, затем вызвать B, я не могу изменить порядок, и мне нужно использовать QueueHandler для входа в систему из нескольких процессов (этот код из длинного и сложного кода, но я сделал это, чтобы быть простым и ясно, но я получил эту проблему в моем исходном коде). Когда вы попробовали этот код с Windows, сообщения не дублируются, но с Linux (Ubuntu 16.04) сообщения дублируются! Я не знаю почему, мне нужно получить тот же результат в Windows (без дубликатов). Что-нибудь, чтобы помочь? это будет с благодарностью. Спасибо!