--- 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,
+ )),
)
--- 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)
+