SORU
13 Mart 2009, Cuma


Nasıl Python çoklu kullanırken günlük etmeli miyim?

Şu anda birden çok işlem 2.6 multiprocessing module Python kullanarak yumurtlar bir çerçeve içinde merkezi bir modül var. multiprocessing kullandığından modül düzey çoklu-farkında günlüğü LOG = multiprocessing.get_logger() var. the docs, başına bu logger şeyler sys.stderr (veya ne olursa olsun filehandle) birden fazla işlemin aynı anda yazması ile iyi çekmiyor kadar kalmamanız paylaşılan işlem kilidi vardır.

Şimdi ben sorunu çerçevesinde diğer modülleri çoklu-farkında değildir. Gördüğüm kadarıyla, bu merkez modülünü kullanın duyarlı Çoklu işlem tüm bağımlılıkları günlüğü yapmak istiyorum. Bu çok sinir bozucuiçindeçerçeve, bırak çerçevesinde tüm müşteriler için. Düşünmüyorum başka alternatif var mı?

CEVAP
21 Mayıs 2009, PERŞEMBE


Sadece bir boru ile üst işlem için her şeyi besleyen sadece kendime ait bir günlük işleyicisi yazdı. Sadece ama oldukça iyi iş gibi görünüyor on dakika boyunca test ettik.

(Not:Bu kendi benim durumumda olan RotatingFileHandler, kodlanmış olur.)


Güncelleme: Uygulama!

Bu eşzamanlılık şimdi sıra doğru bir kullanım kullanır, ve aynı zamanda hatalarını doğru kurtarır. Şimdi birkaç ay için Üretim bu kullanıyorum ve güncel sürüm aşağıda bir sorun olmadan çalışıyor.

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)

        self._handler = RotatingFileHandler(name, mode, maxsize, rotate)
        self.queue = multiprocessing.Queue(-1)

        t = threading.Thread(target=self.receive)
        t.daemon = True
        t.start()

    def setFormatter(self, fmt):
        logging.Handler.setFormatter(self, fmt)
        self._handler.setFormatter(fmt)

    def receive(self):
        while True:
            try:
                record = self.queue.get()
                self._handler.emit(record)
            except (KeyboardInterrupt, SystemExit):
                raise
            except EOFError:
                break
            except:
                traceback.print_exc(file=sys.stderr)

    def send(self, s):
        self.queue.put_nowait(s)

    def _format_record(self, record):
        # ensure that exc_info and args
        # have been stringified.  Removes any chance of
        # unpickleable things inside and possibly reduces
        # message size 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:
            s = self._format_record(record)
            self.send(s)
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            self.handleError(record)

    def close(self):
        self._handler.close()
        logging.Handler.close(self)

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • ravinderosahn

    ravinderosah

    20 Temmuz 2009
  • bored before i even began

    bored before

    30 Mart 2009
  • spederson7

    spederson7

    17 Temmuz 2006