«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Как реализовать ведение журнала с поддержкой многопроцессорной обработки в Python: решение на основе очередей?

Как реализовать ведение журнала с поддержкой многопроцессорной обработки в Python: решение на основе очередей?

Опубликовано 3 ноября 2024 г.
Просматривать:967

  How to Implement Multiprocessing-Aware Logging in Python: A Queue-Based Solution?

Как реализовать ведение журнала с поддержкой многопроцессорной обработки в Python

Многопроцессорная обработка в Python позволяет создавать несколько процессов, которые выполняются независимо. Однако доступ к общим ресурсам, таким как файлы журналов, может стать сложным, поскольку несколько процессов могут пытаться записать в них данные одновременно.

Чтобы избежать этой проблемы, модуль многопроцессорности Python предоставляет возможности ведения журнала с поддержкой многопроцессорности на уровне модуля. Это позволяет средству ведения журнала предотвратить искажение сообщений журнала, гарантируя, что только один процесс одновременно записывает в определенный дескриптор файла.

Однако существующие модули в рамках платформы могут не поддерживать многопроцессорную обработку, что приводит к необходимости для альтернативных решений. Один из подходов предполагает создание специального обработчика журнала, который отправляет сообщения журнала родительскому процессу через канал.

Реализация этого подхода представлена ​​ниже:

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)

Этот пользовательский обработчик журналов позволяет модулям в рамках платформы использовать стандартные методы ведения журнала без необходимости самостоятельно поддерживать многопроцессорную обработку. Сообщения журнала отправляются от дочерних процессов родительскому процессу через канал, гарантируя, что они не будут искажены и правильно записаны в файл журнала.

Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3