--- a/pvl/syslog/rule.py Tue Feb 19 19:28:40 2013 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,216 +0,0 @@
-from pvl.syslog.filter import SyslogFilter
-
-import re
-
-import optparse, sys
-import configobj
-
-import logging; log = logging.getLogger('pvl.syslog.rule')
-
-def parser (parser) :
- """
- Optparse option group.
- """
-
- syslog_rules = optparse.OptionGroup(parser, "Syslog rules")
-
- syslog_rules.add_option('--syslog-rules', metavar='FILE',
- help="Load syslog rules from file")
-
- return syslog_rules
-
-def apply (options) :
- """
- Build SyslogRules from options.
- """
-
- if options.syslog_rules :
- return SyslogRule.load(open(options.syslog_rules))
-
- else :
- return SyslogRule('default', formats={ 'text': '{msg}' })
-
-def merge (*dicts, **kwargs) :
- return dict((k, v) for d in (dicts + (kwargs, )) for k, v in d.iteritems())
-
-# TODO: combine SyslogRule/Rules into one heirarchial SyslogRule -type?
-class SyslogRule (object) :
- """
- A named SyslogFilter with sub-rules.
- """
-
- @classmethod
- def load (cls, file) :
- """
- Load SyslogRule from file.
- """
-
- config = configobj.ConfigObj(file)
-
- return cls.config_section(file.name, config)
-
- @classmethod
- def config_section (cls, name, section) :
- """
- Recursively load Syslogrules from config section.
- """
-
- rules = [cls.config_section(subsection, section[subsection]) for subsection in section.sections]
- attrs = dict((name, section[name]) for name in section.scalars)
-
- try :
- return cls.config(name, rules, **attrs)
-
- except ValueError as ex :
- raise ValueError("[%s] %s" % (name, ex))
-
- @classmethod
- def config_filters (cls, program=None, facility=None, pattern=None, **filters) :
- """
- Return filter expression from given attr/value in config.
- """
-
- # XXX: get rid of these special cases
- if facility :
- yield 'facility', facility # glob
-
- if program :
- yield 'prog', program # glob
-
- if pattern :
- filters['msg'] = pattern
-
- # generic
- for attr, value in filters.iteritems() :
- try :
- # regex
- yield attr, re.compile(value)
-
- except re.error as ex :
- raise ValueError("%s: %s" % (attr, ex))
-
- @classmethod
- def config (cls, name, rules=None, format=None, irk=None, **filters) :
- """
- Build SyslogRule from config options
- """
-
- if format is not None :
- format = { 'text': format }
- else :
- format = { }
-
- if irk :
- format['irk'] = irk
-
- filters = dict(cls.config_filters(**filters))
-
- filter = SyslogFilter(filters)
-
- log.debug("%s: %s %s", name, rules, filter)
-
- return cls(name, rules, filter, format)
-
- def __init__ (self, name, rules=None, filter=None, formats=None) :
- self.name = name
- self.rules = rules or [] # sub-rules
- self.filter = filter # SyslogFilter
- self.formats = formats or {}
-
- def match (self, item) :
- """
- Match item against our filter, returning match-dict (empty?) or None.
- """
-
- if self.filter :
- # filter
- matches = self.filter.filter(item)
-
- else :
- # match all, we probably have sub-rules that we're interested in
- return { }
-
- log.debug("%s: %s", self, matches)
-
- if matches :
- return matches
- else :
- # no match
- return None
-
- def format (self, item) :
- """
- Apply our output formats to given base apply, yielding (unique) attr, value tuples.
- """
-
- for attr, format in self.formats.iteritems() :
- value = format.format(**item)
-
- log.debug("%s: %s: %s", self, attr, value)
-
- yield attr, value
-
- def apply (self, item) :
- """
- Recursively match item against ourself and sub-rules. Returns applied output.
-
- Matches are passed down the tree, and applies are passed up.
- """
-
- log.debug("%s", self)
-
- # match rule -> matches
- matches = self.match(item)
-
- if matches is None :
- # skip
- return None, None, None
-
- # merge matches down
- item = merge(item, matches)
-
- # recursive sub-rules -> apply
- for rule in self.rules :
- try :
- # pass matches down
- match, rules, apply = rule.apply(item)
-
- except Exception as ex :
- log.exception("%s -> %s: %r", self, rule, item)
- continue # XXX: skip?
-
- if apply :
- # pass apply up
- break
- else :
- # self-match
- match, rules, apply = item, [], { }
-
- rules.append(self)
-
- # formats?
- if self.formats :
- # merge apply up
- apply = merge(dict(self.format(item)), apply)
-
- log.debug("%s: %s", '/'.join(str(rule) for rule in rules), apply)
-
- return match, rules, apply
-
- def __iter__ (self, items) :
- """
- Apply items against our rules, yielding any matches.
- """
-
- for item in items :
- match, rules, apply = self.apply(item)
-
- if apply :
- yield apply
-
- def __str__ (self) :
- return self.name
-
- def __repr__ (self) :
- return 'SyslogRule({self.name}, ...)'.format(self=self)
-