Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk Melaksanakan Pengelogan Berbilang Pemprosesan dalam Python: Penyelesaian Berasaskan Baris?

Bagaimana untuk Melaksanakan Pengelogan Berbilang Pemprosesan dalam Python: Penyelesaian Berasaskan Baris?

Susan Sarandon
Susan Sarandonasal
2024-10-30 12:14:02554semak imbas

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

Cara Melaksanakan Pengelogan Sedar Berbilang Pemprosesan dalam Python

Pemprosesan berbilang dalam Python membenarkan penciptaan berbilang proses yang berjalan secara bebas. Walau bagaimanapun, mengakses sumber kongsi seperti fail log boleh menjadi rumit kerana berbilang proses mungkin cuba menulis kepada mereka secara serentak.

Untuk mengelakkan isu ini, modul berbilang pemprosesan Python menyediakan keupayaan pengelogan berbilang pemprosesan-sedar modul peringkat. Ini membolehkan pembalak mengelakkan kekacauan mesej log dengan memastikan hanya satu proses menulis kepada deskriptor fail tertentu pada satu masa.

Walau bagaimanapun, modul sedia ada dalam rangka kerja mungkin tidak menyedari pelbagai pemprosesan, yang membawa kepada keperluan untuk penyelesaian alternatif. Satu pendekatan melibatkan mencipta pengendali log tersuai yang menghantar mesej pengelogan kepada proses induk melalui paip.

Pelaksanaan pendekatan ini disediakan di bawah:

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)

Pengendali log tersuai ini membenarkan modul dalam rangka kerja untuk menggunakan amalan pembalakan standard tanpa perlu sedar diri berbilang pemprosesan. Mesej log dihantar daripada proses anak kepada proses induk melalui paip, memastikan ia tidak bercelaru dan ditulis dengan betul pada fail log.

Atas ialah kandungan terperinci Bagaimana untuk Melaksanakan Pengelogan Berbilang Pemprosesan dalam Python: Penyelesaian Berasaskan Baris?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn