from pvl.syslog.filter import SyslogFilter
import re
import optparse, sys
import logging; log = logging.getLogger('pvl.syslog.rule')
# XXX: ConfigParser kinda sucks
import ConfigParser
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 SyslogRules.load(open(options.syslog_rules))
else :
return None
# TODO: combine SyslogRule/Rules into one heirarchial SyslogRule -type?
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) :
log.debug("%s: %s", tag, pattern)
if pattern :
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.
Returns
None - skip
False - drop
(tag, line) - output
"""
# filter
match = self.filter.filter(item)
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)
def __str__ (self) :
return self.tag
class SyslogRules (object) :
"""
Apply a set of rules against lines.
"""
@classmethod
def load (cls, file) :
"""
Load rules from file.
"""
config = ConfigParser.RawConfigParser()
config.readfp(file)
# XXX: ordered in python2.7, unordered in python2.6 !
rules = [SyslogRule(section, **dict(config.items(section))) for section in config.sections()]
return cls(rules)
def __init__ (self, rules) :
self.rules = rules
def apply (self, item) :
"""
Apply item against our rules, returning the first match (False/tag-line).
"""
for rule in self.rules :
try :
match = rule.apply(item)
except Exception as ex :
log.exception("rule %s: %r", rule, item)
continue
log.debug("%s: %s", rule, match)
if match is None :
continue
else :
break
return match
def process (self, items) :
"""
Apply items against our rules, yielding any matches.
"""
for item in items :
match = self.apply(item)
if match :
yield match