logstash的tcp input 和 python logging 模块

logstash的 tcp和 syslog input plugin 都是把tcp流直接当做日志数据的; 而 logging模块里的SocketHandler输出的是经过pickle 序列化的,可以参考官方的接收端代码例子:

import pickle
import logging
import logging.handlers
import SocketServer
import struct


class LogRecordStreamHandler(SocketServer.StreamRequestHandler):
    """Handler for a streaming logging request.

    This basically logs the record using whatever logging policy is
    configured locally.
    """

    def handle(self):
        """
        Handle multiple requests - each expected to be a 4-byte length,
        followed by the LogRecord in pickle format. Logs the record
        according to whatever policy is configured locally.
        """
        while True:
            chunk = self.connection.recv(4)
            if len(chunk) < 4:
                break
            slen = struct.unpack('>L', chunk)[0]
            chunk = self.connection.recv(slen)
            while len(chunk) < slen:
                chunk = chunk + self.connection.recv(slen - len(chunk))
            obj = self.unPickle(chunk)
            record = logging.makeLogRecord(obj)
            self.handleLogRecord(record)

    def unPickle(self, data):
        return pickle.loads(data)

    def handleLogRecord(self, record):
        # if a name is specified, we use the named logger rather than the one
        # implied by the record.
        if self.server.logname is not None:
            name = self.server.logname
        else:
            name = record.name
        logger = logging.getLogger(name)
        # N.B. EVERY record gets logged. This is because Logger.handle
        # is normally called AFTER logger-level filtering. If you want
        # to do filtering, do it at the client end to save wasting
        # cycles and network bandwidth!
        logger.handle(record)

class LogRecordSocketReceiver(SocketServer.ThreadingTCPServer):
    """
    Simple TCP socket-based logging receiver suitable for testing.
    """

    allow_reuse_address = 1

    def __init__(self, host='localhost',
                 port=logging.handlers.DEFAULT_TCP_LOGGING_PORT,
                 handler=LogRecordStreamHandler):
        SocketServer.ThreadingTCPServer.__init__(self, (host, port), handler)
        self.abort = 0
        self.timeout = 1
        self.logname = None

    def serve_until_stopped(self):
        import select
        abort = 0
        while not abort:
            rd, wr, ex = select.select([self.socket.fileno()],
                                       [], [],
                                       self.timeout)
            if rd:
                self.handle_request()
            abort = self.abort

def main():
    logging.basicConfig(
        format='%(relativeCreated)5d %(name)-15s %(levelname)-8s %(message)s')
    tcpserver = LogRecordSocketReceiver()
    print('About to start TCP server...')
    tcpserver.serve_until_stopped()

if __name__ == '__main__':
    main()

 

 

不过还是可以用logging.StreamHandler直接输出日志数据:

class logging.StreamHandler(stream=None)

Returns a new instance of the StreamHandler class. If stream is specified, the instance will use it for logging output; otherwise, sys.stderr will be used.

import logging,socket
from logging.handlers import RotatingFileHandler, SysLogHandler, SocketHandler
# StreamHandler直接在logging模块里

#logging.basicConfig(level=logging.DEBUG,
#                format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
#                datefmt='%a, %d %b %Y %H:%M:%S',
#                filename='/home/ubuntu/zhenghai.tan/pylog/myapp.log',
#                filemode='w')


logging.getLogger('').setLevel(logging.DEBUG)
mylogger = logging.getLogger('mylog')

host = '172.19.1.143'  
port = 2015
bufsize = 10240  
addr = (host,port)  
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)  
client.connect(addr)  

tcplog = logging.StreamHandler(client.makefile())
formatter = logging.Formatter('%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
tcplog.setFormatter(formatter)
tcplog.setLevel(logging.DEBUG)
mylogger.addHandler(tcplog)

mylogger.debug('This is a debug message')
mylogger.info('This is a info message')
mylogger.warning('This is a warn message')

 


posted on 2015-09-06 14:14  不忘初衷,方能致远  阅读(1144)  评论(0)    收藏  举报

导航