# HG changeset patch # User Tero Marttila # Date 1265395101 -7200 # Node ID 342850300d6ab037c0a9975711b13264bc182ddb # Parent edbc337b7c2999063b4d97074c8c545437f9db11 implement UnixDatagramSocket and LogSource.handleMessage diff -r edbc337b7c29 -r 342850300d6a etc/fixbot-logwatch.py --- a/etc/fixbot-logwatch.py Fri Feb 05 20:37:51 2010 +0200 +++ b/etc/fixbot-logwatch.py Fri Feb 05 20:38:21 2010 +0200 @@ -18,4 +18,7 @@ filters.su_nobody_killer, filters.all, )), + UnixDatagramSocket("test", os.path.join(logwatch_dir, "test.sock"), ( + filters.all, + )), ) diff -r edbc337b7c29 -r 342850300d6a fixbot/logwatch/sources.py --- a/fixbot/logwatch/sources.py Fri Feb 05 20:37:51 2010 +0200 +++ b/fixbot/logwatch/sources.py Fri Feb 05 20:38:21 2010 +0200 @@ -2,10 +2,11 @@ Implementations of the various sources of log data """ -from twisted.internet import protocol +from twisted.internet import protocol, reactor from twisted.python import log from fixbot import fifo +from fixbot.logwatch import message class LogSource (object) : """ @@ -39,20 +40,44 @@ def handleData (self, data) : """ - Buffer the given chunk of data, passing any full lines to handleLine + Feed binary data into the buffer, processing all lines via handleLine() """ data = self.buf + data while "\n" in data : line, data = data.split("\n", 1) - + + # full line self.handleLine(line) self.buf = data def handleLine (self, line) : - log.msg("Matching line `%s'..." % line) + """ + Parse given line into a SyslogMessage, and pass it to handleMessage + """ + + # parse + try : + msg = message.SyslogMessage(line) + + except Exception, e : + # log and ignore + log.err(e, "Invalid syslog message from source %s: %s" % (self.name, line)) + + else : + # handle the structured message + self.handleMessage(msg) + + def handleMessage (self, msg) : + """ + Process the given SyslogMessage + """ + + # XXX: filters should accept messages... + line = str(msg) + log.msg(repr(msg)) for filter in self.filters : # let the filter process the line @@ -129,4 +154,28 @@ super(Fifo, self).connectionLost(reason) self.handleError("lost fifo for %s: %s" % (self.name, reason.getErrorMessage())) +class UnixDatagramSocket (LogSource, protocol.DatagramProtocol) : + """ + Stream messages from a UNIX datagram socket + """ + + # maximum size of the recieved messages + # native syslog is 1024, but syslog-ng does better... so 4k + MAX_PACKET_SIZE = 4096 + def __init__ (self, name, path, filters) : + LogSource.__init__(self, name, filters) + + log.msg("opening unix socket for %s at: %s" % (name, path)) + + # open UNIX socket + reactor.listenUNIXDatagram(path, self, self.MAX_PACKET_SIZE) + + def datagramReceived (self, data, addr) : + """ + Got message from syslog-ng + """ + + # handle it as a line of data + self.handleLine(data) +