用zeromq的PUB/SUB網絡模型擴充python logging

zeromq是一個快速的通訊庫。有好幾個語言的擴展綁定。今天用它的python擴展庫,爲標準的logging庫實現一個ZMQPUBHandler。
使用這個ZMQPUBHandler,能監聽機器的某端口,然後將log信息發佈(zmq.PUB)到那端口。用zeromq實現的好處是,代碼實現簡單,信息發佈socket只是不斷髮送數據就行,不用理會是否有人訂閱這些信息;允許多個訂閱(zmq.SUB)客戶連接過來,訂閱的代碼實現也很簡單,都不需要考慮斷開連接的問題。
import os, sys, types
import zmq, logging
import time

class ZMQPUBHandler(logging.Handler):
    def __init__(self, host, port):
        logging.Handler.__init__(self)
        ctx = zmq.Context(1,1)
        self.sock = ctx.socket(zmq.PUB)
        self.sock.bind('tcp://%s:%s' %(host, port))

    def emit(self, record):
        """
        Emit a record.

        If a formatter is specified, it is used to format the record.
        The record is then written to the stream with a trailing newline
        [N.B. this may be removed depending on feedback]. If exception
        information is present, it is formatted using
        traceback.print_exception and appended to the stream.
        """
        try:
            msg = self.format(record)
            fs = "%s\n"
            if not hasattr(types, "UnicodeType"): #if no unicode support...
                self.sock.send(fs % msg, zmq.NOBLOCK)
            else:
                try:
                    self.sock.send(fs % msg, zmq.NOBLOCK)
                except UnicodeError:
                    self.sock.send(fs % msg.encode("UTF-8"), zmq.NOBLOCK)
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            self.handleError(record)


def main():
    #訂閱
    host = sys.argv[1]
    ctx = zmq.Context(1, 1)
    sock = ctx.socket(zmq.SUB)
    sock.setsockopt(zmq.SUBSCRIBE, '')
    sock.connect('tcp://%s:55555' % host)

    while 1:
        msg = sock.recv(zmq.NOBLOCK)
        if msg:
            print msg,
        else:
            time.sleep(0.1)

if __name__ == '__main__':
    main()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章