move logwatch*.py to separate fixbot.logwatch package, and move logwatch_sources to etc/fixbot-logwatch.py
authorTero Marttila <terom@fixme.fi>
Thu, 04 Feb 2010 19:40:51 +0200
changeset 40 b9fdb7710768
parent 39 e82b6df5baa3
child 41 9be5b4525e78
move logwatch*.py to separate fixbot.logwatch package, and move logwatch_sources to etc/fixbot-logwatch.py
etc/fixbot-logwatch.py
fixbot/logwatch.py
fixbot/logwatch/__init__.py
fixbot/logwatch/filters.py
fixbot/logwatch/logwatch.py
fixbot/logwatch/sources.py
fixbot/logwatch_filters.py
fixbot/logwatch_sources.py
twisted/plugins/fixbot_logwatch_plugin.py
--- a/etc/fixbot-logwatch.py	Thu Feb 04 19:39:37 2010 +0200
+++ b/etc/fixbot-logwatch.py	Thu Feb 04 19:40:51 2010 +0200
@@ -1,19 +1,15 @@
-import logwatch_filters as filters
-from logwatch_sources import *
-
-def sources () :
-    """
-        Return a sequence of LogSource objects
-    """
+from fixbot.logwatch import filters
+from fixbot.logwatch.sources import *
 
-    return (
-        Fifo("auth", "logs/auth.fifo", (
-            filters.sudo,
-            filters.cron_killer,
-            filters.all,
-        )),
-        Fifo("foo", "foo", (
-            filters.all,
-        )),
-    )
+## shared secret for API client
+api_secret = "xyz"
 
+## Path to logfiles
+logwatch_dir = "logs/"
+
+## Iterable of LogSource objects
+logwatch_sources = (
+    Fifo("test", logwatch_dir + "/test.fifo", (
+        filters.all,
+    )),
+)
--- a/fixbot/logwatch.py	Thu Feb 04 19:39:37 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-from twisted.internet import protocol, reactor
-from twisted.python import log
-import sys
-
-import api
-#import logwatch_config as config
-
-class LogWatchModule (api.Module) :
-    name = "logs"
-    version = 0x0005
-    
-    event_types = [
-        "error",
-        "sudo",
-        "ssh",
-        "all"
-    ]
-    
-    def handleConnect (self) :
-        for source in config.sources() :
-            source.setModule(self)
-    
-    def error (self, msg) :
-        self.sendEvent("error", msg)
-
-def makeService (config) :
-    return api.makeService(LogWatchModule, config)
-
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fixbot/logwatch/filters.py	Thu Feb 04 19:40:51 2010 +0200
@@ -0,0 +1,66 @@
+import re
+
+class FullFilter (object) :
+    def __init__ (self, event_type) :
+        self.event_type = event_type
+
+    def test (self, line) :
+        return line
+
+class NullFilter (object) :
+    def __init__ (self, pattern, flags=None) :
+        self.regexp = re.compile(pattern, flags)
+    
+    def test (self, line) :
+        match = self.regexp.search(line)
+        
+        if match :
+            return False
+
+class SimpleFilter (object) :
+    def __init__ (self, event_type, pattern, format) :
+        self.event_type = event_type
+
+        self.regexp = re.compile(pattern)
+        self.format = format
+
+    def test (self, line) :
+        match = self.regexp.search(line)
+        
+        if match :
+            return self._filter(match)
+        
+    def _filter (self, match) :
+        return self.format % match.groupdict()
+
+_timestamp = "\w{3} [0-9 ]\d \d{2}:\d{2}:\d{2}"
+
+all = FullFilter("all")
+
+all_wo_timestamps = SimpleFilter(
+    "all",
+    "^" + _timestamp + " (?P<line>.+)$",
+    "%(line)s"
+)
+
+sudo = SimpleFilter(
+    "sudo",
+    "(?P<hostname>\S+)\s+sudo:\s*(?P<username>\S+) : TTY=(?P<tty>\S+) ; PWD=(?P<pwd>.+?) ; USER=(?P<target_user>\S+) ; COMMAND=(?P<command>.*)",
+    "%(username)s:%(tty)s - %(target_user)s@%(hostname)s:%(pwd)s - %(command)r"
+)
+
+ssh = SimpleFilter(
+    "ssh",
+    "(?P<success>Accepted|Failed) password for (?P<username>\S+) from (?P<ip>\S+) port (?P<port>\S+) (?P<proto>\S+)",
+    "%(success)s login for %(username)s from %(ip)s:%(port)s proto %(proto)s"
+)
+
+cron_killer = NullFilter(
+        "^" + _timestamp + " \S+\s+(CRON|su)\[\d+\]: pam_unix\(cron:\w+\): session (opened|closed) for user \w+( by \(uid=\d+\))?$",
+        re.IGNORECASE
+)
+
+su_nobody_killer = NullFilter(
+    "^" + _timestamp + " \S+\s+su\[\d+\]: (Successful su for nobody by root|\+ \?\?\? root:nobody)$",
+    re.IGNORECASE
+)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fixbot/logwatch/logwatch.py	Thu Feb 04 19:40:51 2010 +0200
@@ -0,0 +1,36 @@
+from twisted.internet import protocol, reactor
+from twisted.python import log
+import sys
+
+from fixbot import api
+
+class LogWatchModule (api.Module) :
+    name = "logs"
+    version = 0x0005
+    
+    event_types = [
+        "error",
+        "sudo",
+        "ssh",
+        "all"
+    ]
+
+    def __init__ (self, config) :
+        """
+            Initialize with logwatch_sources from config
+        """
+
+        super(LogWatchModule, self).__init__(config)
+
+        self.sources = config['logwatch-sources']
+    
+    def handleConnect (self) :
+        for source in self.sources :
+            source.setModule(self)
+    
+    def error (self, msg) :
+        self.sendEvent("error", msg)
+
+def makeService (config) :
+    return api.makeService(LogWatchModule, config)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fixbot/logwatch/sources.py	Thu Feb 04 19:40:51 2010 +0200
@@ -0,0 +1,105 @@
+from twisted.internet import reactor, protocol
+from twisted.python import log
+
+from fixbot 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 :
+            # let the filter process the line
+            out = filter.test(line)
+
+            if out :
+                # positive match, send
+                log.msg("\t%s: %s" % (filter.event_type, out))
+                self.module.sendEvent(filter.event_type, out)
+
+                break
+
+            elif out is False :
+                # negative match, stop processing
+                return
+
+            else :  # None
+                # no match
+                continue
+
+class File (LogSource, protocol.ProcessProtocol) :
+    """
+        Stream lines from a regular file using /usr/bin/tail -f
+    """
+
+    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) :
+    """
+        Stream lines from a fifo object.
+    """
+
+    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()))
+
+
--- a/fixbot/logwatch_filters.py	Thu Feb 04 19:39:37 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-import re
-
-class FullFilter (object) :
-    def __init__ (self, event_type) :
-        self.event_type = event_type
-
-    def test (self, line) :
-        return line
-
-class NullFilter (object) :
-    def __init__ (self, pattern, flags=None) :
-        self.regexp = re.compile(pattern, flags)
-    
-    def test (self, line) :
-        match = self.regexp.search(line)
-        
-        if match :
-            return False
-
-class SimpleFilter (object) :
-    def __init__ (self, event_type, pattern, format) :
-        self.event_type = event_type
-
-        self.regexp = re.compile(pattern)
-        self.format = format
-
-    def test (self, line) :
-        match = self.regexp.search(line)
-        
-        if match :
-            return self._filter(match)
-        
-    def _filter (self, match) :
-        return self.format % match.groupdict()
-
-_timestamp = "\w{3} [0-9 ]\d \d{2}:\d{2}:\d{2}"
-
-all = FullFilter("all")
-
-all_wo_timestamps = SimpleFilter(
-    "all",
-    "^" + _timestamp + " (?P<line>.+)$",
-    "%(line)s"
-)
-
-sudo = SimpleFilter(
-    "sudo",
-    "(?P<hostname>\S+)\s+sudo:\s*(?P<username>\S+) : TTY=(?P<tty>\S+) ; PWD=(?P<pwd>.+?) ; USER=(?P<target_user>\S+) ; COMMAND=(?P<command>.*)",
-    "%(username)s:%(tty)s - %(target_user)s@%(hostname)s:%(pwd)s - %(command)r"
-)
-
-ssh = SimpleFilter(
-    "ssh",
-    "(?P<success>Accepted|Failed) password for (?P<username>\S+) from (?P<ip>\S+) port (?P<port>\S+) (?P<proto>\S+)",
-    "%(success)s login for %(username)s from %(ip)s:%(port)s proto %(proto)s"
-)
-
-cron_killer = NullFilter(
-        "^" + _timestamp + " \S+\s+(CRON|su)\[\d+\]: pam_unix\(cron:\w+\): session (opened|closed) for user \w+( by \(uid=\d+\))?$",
-        re.IGNORECASE
-)
-
-su_nobody_killer = NullFilter(
-    "^" + _timestamp + " \S+\s+su\[\d+\]: (Successful su for nobody by root|\+ \?\?\? root:nobody)$",
-    re.IGNORECASE
-)
--- a/fixbot/logwatch_sources.py	Thu Feb 04 19:39:37 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-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()))
-
-
--- a/twisted/plugins/fixbot_logwatch_plugin.py	Thu Feb 04 19:39:37 2010 +0200
+++ b/twisted/plugins/fixbot_logwatch_plugin.py	Thu Feb 04 19:40:51 2010 +0200
@@ -6,11 +6,12 @@
 
 from twisted.application import internet
 
-from fixbot import api, logwatch
+from fixbot import api
+from fixbot.logwatch import logwatch
 
 class LogwatchOptions (api.ClientOptions) :
     optParameters = [
-
+        ("logwatch-sources",    None,   None,   "See etc/fixbot-logwatch.py"),
     ]
 
     optFlags = [