zeromq是一个快速的通讯库。有好几个语言的扩展绑定。今天用它的python扩展库,为标准的logging库实现一个ZMQPUBHandler。
使用这个ZMQPUBHandler,能监听机器的某端口,然后将log信息发布(zmq.PUB)到那端口。用zeromq实现的好处是,代码实现简单,信息发布socket只是不断发送数据就行,不用理会是否有人订阅这些信息;允许多个订阅(zmq.SUB)客户连接过来,订阅的代码实现也很简单,都不需要考虑断开连接的问题。
Python语言:
用zeromq的PUB/SUB网络模型扩充python logging
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()
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()
转载于:https://blog.51cto.com/seewind/288343