move logwatch*.py to separate fixbot.logwatch package, and move logwatch_sources to etc/fixbot-logwatch.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 = [