pvl.syslog: SyslogRule
authorTero Marttila <terom@fixme.fi>
Thu, 03 Jan 2013 13:04:51 +0200
changeset 45 10dfa434da77
parent 44 977442ccb72d
child 46 0bdbbda4cdea
pvl.syslog: SyslogRule
bin/pvl.verkko-syslog
pvl/syslog/filter.py
pvl/syslog/rule.py
--- a/bin/pvl.verkko-syslog	Thu Jan 03 00:56:28 2013 +0200
+++ b/bin/pvl.verkko-syslog	Thu Jan 03 13:04:51 2013 +0200
@@ -31,15 +31,8 @@
     
     # options
     parser.add_option_group(pvl.args.parser(parser))
-
-    ## syslog
     parser.add_option_group(pvl.syslog.args.parser(parser))
 
-    # defaults
-    parser.set_defaults(
-
-    )
-    
     # parse
     options, args = parser.parse_args(argv[1:])
     
@@ -48,6 +41,15 @@
 
     return options, args
 
+# prototype
+import pvl.syslog.rule
+
+sudo = pvl.syslog.rule.SyslogRule('sudo',
+    program = 'sudo',
+    pattern = r'\s*(?P<login>\S+) : TTY=(?P<tty>\S+) ; PWD=(?P<pwd>.+?) ; USER=(?P<user>\S+) ; (?:ENV=(?P<env>.+?) ; )?COMMAND=(?P<command>.*)',
+    format  = "{login}:{tty} - {user}@{host}:{pwd} - {env}{command!r}",
+)
+
 def main (argv) :
     options, args = parse_options(argv)
     
@@ -56,7 +58,7 @@
     log.info("Start processing syslog messages...")
 
     for item in syslog.loop() :
-        print item
+        print sudo.apply(item)
     
     # done
     log.info("Exiting...")
--- a/pvl/syslog/filter.py	Thu Jan 03 00:56:28 2013 +0200
+++ b/pvl/syslog/filter.py	Thu Jan 03 13:04:51 2013 +0200
@@ -2,14 +2,16 @@
 
 class SyslogFilter (object) :
     """
-        Filter syslog messages.
+        Match syslog messages.
+
+        XXX: do we need more than just prog?
     """
 
     def __init__ (self, prog=None) :
         """
             prog        - match tag (process name)
         """
-
+        
         self.prog = prog
 
     def match_prog (self, prog) :
@@ -17,6 +19,9 @@
             Match given prog?
         """
 
+        if not self.prog :
+            return
+
         # normalize
         prog = prog.lower()
 
@@ -41,12 +46,26 @@
             Match given item?
         """
 
-        if self.prog and not self.match_prog(item['prog']) :
-            log.debug("prog: %s: %r", self.prog, item['prog'])
+        for attr, func in (
+            ( 'prog',   self.match_prog),
+        ) :
+            match = func(item[attr])
 
+            if match :
+                continue
+            
+            elif match is None :
+                pass
+
+            else :
+                break
+        
+        # ok
+        if match is None :
+            # XXX: empty filter!?
+            return True
         else :
-            # ok
-            return True
+            return match
 
     def __call__ (self, items) :
         for item in items:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pvl/syslog/rule.py	Thu Jan 03 13:04:51 2013 +0200
@@ -0,0 +1,54 @@
+from pvl.syslog.filter import SyslogFilter
+
+import re
+
+import logging; log = logging.getLogger('pvl.syslog.rule')
+
+class SyslogRule (object) :
+    """
+        A rule matches syslog lines, and formats them.
+            
+            tag         - apply given tag to matches
+    """
+        
+    def __init__ (self, tag, program=None, pattern=None, format=None, flags=0) :
+        pattern = re.compile(pattern, flags)
+
+        self.filter = SyslogFilter(prog=program)
+
+        self.tag = tag
+        self.format = format
+        self.pattern = pattern
+
+    def apply (self, item) :
+        """
+            Apply rule against given item.
+        """
+        
+        # filter
+        match = self.filter.filter(item)
+
+        log.debug("filter: %s", match)
+
+        if not match :
+            # ignore
+            return None
+        
+        if self.pattern :
+            match = self.pattern.match(item['msg'])
+
+            if not match :
+                # ignore
+                return None
+            
+            # apply
+            item.update(match.groupdict())
+
+        if self.tag is False :
+            # drop
+            return False
+            
+        if self.format :
+            # return
+            return self.tag, self.format.format(**item)
+