from twisted.internet import reactor, protocol
from twisted.python import log
import fifo
class LogSource (object) :
def __init__ (self, name, filters) :
# set later on
self.module = None
# what filters to apply
self.filters = filters
# name, for display purposes
self.name = name
# used to gather data together into lines
self.buf = ""
def setModule (self, module) :
self.module = module
def handleError (self, msg) :
log.err(msg)
self.module.error(msg)
def handleData (self, data) :
data = self.buf + data
while "\n" in data :
line, data = data.split("\n", 1)
self.handleLine(line)
self.buf = data
def handleLine (self, line) :
log.msg("Matching line `%s'..." % line)
for filter in self.filters :
out = filter.test(line)
if out :
log.msg("\t%s: %s" % (filter.event_type, out))
self.module.sendEvent(filter.event_type, out)
break
elif out is False :
return
else : # None
continue
class File (LogSource, protocol.ProcessProtocol) :
def __init__ (self, name, path, filters) :
super(File, self).__init__(name, filters)
self.path = path
log.msg("spawning tail process for %s:%s" % (name, path))
reactor.spawnProcess(self, "/usr/bin/tail", ["tail", "-n0", "--follow=name", path])
def errReceived (self, data) :
self.handleError("tail for %s: %s" % (self.name, data))
def outReceived (self, data) :
self.handleData(data)
def processEnded (self, reason) :
self.handleError("tail process for %s quit: %s" % (self.name, reason.getErrorMessage()))
class Fifo (LogSource, fifo.Fifo) :
def __init__ (self, name, path, filters) :
LogSource.__init__(self, name, filters)
log.msg("opening fifo for %s:%s" % (name, path))
fifo.Fifo.__init__(self, path)
def dataReceived (self, data) :
self.handleData(data)
def handleEOF (self) :
self.handleError("!!! EOF on fifo %s, re-opening" % self.name)
self.reopen()
def connectionLost (self, reason) :
super(Fifo, self).connectionLost(reason)
self.handleError("lost fifo for %s: %s" % (self.name, reason.getErrorMessage()))