Como implementar o log com reconhecimento de multiprocessamento em Python
O multiprocessamento em Python permite a criação de vários processos que são executados de forma independente. No entanto, acessar recursos compartilhados, como arquivos de log, pode se tornar complexo, pois vários processos podem tentar gravar neles simultaneamente.
Para evitar esse problema, o módulo de multiprocessamento Python fornece recursos de registro em log com reconhecimento de multiprocessamento em nível de módulo. Isso permite que o criador de logs evite distorções nas mensagens de log, garantindo que apenas um processo grave em um descritor de arquivo específico por vez.
No entanto, os módulos existentes na estrutura podem não ter reconhecimento de multiprocessamento, levando à necessidade para soluções alternativas. Uma abordagem envolve a criação de um manipulador de log personalizado que envia mensagens de registro para o processo pai por meio de um canal.
Uma implementação dessa abordagem é fornecida abaixo:
from logging.handlers import RotatingFileHandler import multiprocessing, threading, logging, sys, traceback class MultiProcessingLog(logging.Handler): def __init__(self, name, mode, maxsize, rotate): logging.Handler.__init__(self) # Set up the file handler for the parent process self._handler = RotatingFileHandler(name, mode, maxsize, rotate) # Create a queue to receive log messages from child processes self.queue = multiprocessing.Queue(-1) # Start a thread in the parent process to receive and log messages t = threading.Thread(target=self.receive) t.daemon = True t.start() def receive(self): while True: try: # Get a log record from the queue record = self.queue.get() # Log the record using the parent process's file handler self._handler.emit(record) # Exit the thread if an exception is raised except (KeyboardInterrupt, SystemExit): raise except EOFError: break except: traceback.print_exc(file=sys.stderr) def send(self, s): # Put the log record into the queue for the receiving thread self.queue.put_nowait(s) def _format_record(self, record): # Stringify any objects in the record to ensure that they can be sent over the pipe if record.args: record.msg = record.msg % record.args record.args = None if record.exc_info: dummy = self.format(record) record.exc_info = None return record def emit(self, record): try: # Format and send the log record through the pipe s = self._format_record(record) self.send(s) except (KeyboardInterrupt, SystemExit): raise except: self.handleError(record) def close(self): # Close the file handler and the handler itself self._handler.close() logging.Handler.close(self)
Este manipulador de log personalizado permite que os módulos dentro da estrutura usem práticas de registro padrão sem precisar estar cientes do multiprocessamento. As mensagens de log são enviadas dos processos filhos para o processo pai por meio de um canal, garantindo que não sejam distorcidas e gravadas corretamente no arquivo de log.
Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.
Copyright© 2022 湘ICP备2022001581号-3