from twisted.internet import protocol, reactor
from twisted.python import log
import sys, re
import api
class TailProcessProtocol (protocol.ProcessProtocol) :
def __init__ (self, module, name, filters) :
self.module = module
self.name = name
self.filters = filters
self.buf = ""
def errReceived (self, data) :
self.module.error("tail for %s: %s" % (self.name, data))
def outReceived (self, data) :
data = self.buf + data
while "\n" in data :
line, data = data.split("\n", 1)
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)
self.buf = data
def processEnded (self, reason) :
msg = "tail process for %s quit: %s" % (self.name, reason.getErrorMessage())
log.err(msg)
self.module.error(msg)
class Filter (object) :
def __init__ (self, regexp, event_type) :
self.regexp = re.compile(regexp)
self.event_type = event_type
def test (self, line) :
match = self.regexp.search(line)
if match :
return self._filter(match)
def _filter (self, match) :
return match.string
class SudoFilter (Filter) :
REGEXP = "sudo:\s*(?P<username>\S+) : TTY=(?P<tty>\S+) ; PWD=(?P<pwd>.+?) ; USER=(?P<target_user>\S+) ; COMMAND=(?P<command>.*)"
def __init__ (self) :
super(SudoFilter, self).__init__(self.REGEXP, "sudo")
def _filter (self, match) :
return "%(username)s:%(tty)s - %(pwd)s - `%(command)s` as %(target_user)s" % match.groupdict()
class ExampleModule (api.Module) :
name = "logs"
version = 0x0001
event_types = [
"error",
"sudo"
]
log_files = (
("auth.log", "/var/log/auth.log", (
SudoFilter(),
)),
)
log_objs = None
def handleConnect (self) :
log.msg("Spawning tail processes...")
self.log_objs = dict()
for name, file, filters in self.log_files :
log.msg("\t%s - %s..." % (name, file))
p = self.log_objs[name] = TailProcessProtocol(self, name, filters)
reactor.spawnProcess(p, "/usr/bin/tail", ["tail", "--follow=name", file])
def error (self, msg) :
self.sendEvent("error", msg)
if __name__ == '__main__' :
log.startLogging(sys.stderr)
module = ExampleModule()
reactor.run()