--- a/pvl/syslog/args.py Thu Jan 03 00:38:26 2013 +0200
+++ b/pvl/syslog/args.py Thu Jan 03 00:56:28 2013 +0200
@@ -1,6 +1,7 @@
import optparse, sys
from pvl.syslog.parser import SyslogParser
+from pvl.syslog.filter import SyslogFilter
from pvl.syslog.syslog import SyslogSource
from pvl.syslog import fifo, tail
@@ -62,14 +63,18 @@
else :
log.error("No --syslog source given")
sys.exit(2)
-
+
parser = SyslogParser(
raw = options.syslog_raw,
+ )
+
+ filter = SyslogFilter(
prog = options.syslog_prog,
)
# build
return SyslogSource(source, parser,
- poll = poll
+ filter = filter,
+ poll = poll,
)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pvl/syslog/filter.py Thu Jan 03 00:56:28 2013 +0200
@@ -0,0 +1,55 @@
+import logging; log = logging.getLogger('pvl.syslog.filter')
+
+class SyslogFilter (object) :
+ """
+ Filter syslog messages.
+ """
+
+ def __init__ (self, prog=None) :
+ """
+ prog - match tag (process name)
+ """
+
+ self.prog = prog
+
+ def match_prog (self, prog) :
+ """
+ Match given prog?
+ """
+
+ # normalize
+ prog = prog.lower()
+
+ if prog.startswith('/') :
+ # base
+ prog = prog.split('/')[-1]
+
+ # match
+ if not prog :
+ # never matches non-tagged lines
+ return False
+
+ elif self.prog.endswith('*') :
+ # prefix match
+ return prog.startswith(self.prog[:-1])
+
+ else :
+ return prog == self.prog
+
+ def filter (self, item) :
+ """
+ Match given item?
+ """
+
+ if self.prog and not self.match_prog(item['prog']) :
+ log.debug("prog: %s: %r", self.prog, item['prog'])
+
+ else :
+ # ok
+ return True
+
+ def __call__ (self, items) :
+ for item in items:
+ if self.filter(item) :
+ yield item
+
--- a/pvl/syslog/parser.py Thu Jan 03 00:38:26 2013 +0200
+++ b/pvl/syslog/parser.py Thu Jan 03 00:56:28 2013 +0200
@@ -1,7 +1,3 @@
-"""
- Parse syslog lines in text format.
-"""
-
import datetime, time
import re
@@ -9,7 +5,7 @@
class SyslogParser (object) :
"""
- A source of syslog items.
+ Parse syslog lines in text format, as used in logfiles/fifos.
"""
# default syslogd format
@@ -23,13 +19,12 @@
TIMESTAMP_FMT = '%b %d %H:%M:%S'
- def __init__ (self, raw=False, prog=None) :
+ def __init__ (self, raw=False) :
"""
Using given underlying line source.
"""
self.raw = raw
- self.prog = prog
def parse_timestamp (self, match) :
"""
@@ -53,18 +48,11 @@
prog = match.group('program')
- if not prog :
+ if prog :
+ return prog
+ else :
# no tag
return None
-
- # normalize
- prog = prog.lower()
-
- if prog.startswith('/') :
- # base
- prog = prog.split('/')[-1]
-
- return prog
def parse (self, line) :
"""
@@ -83,7 +71,7 @@
return dict(
timestamp = datetime.datetime.now(), # XXX: None?
host = None,
- prog = self.prog,
+ prog = None,
pid = None,
msg = line,
)
@@ -105,37 +93,6 @@
msg = match.group('text'),
)
- def match_prog (self, prog) :
- """
- Match given prog?
- """
-
- if not prog :
- # never matches non-tagged lines
- return False
-
- elif self.prog.endswith('*') :
- # prefix match
- return prog.startswith(self.prog[:-1])
- else :
- return prog == self.prog
-
-
- def filter (self, line, item) :
- """
- Filter given item?
- """
-
- if not item :
- log.debug("empty: %r", line)
-
- elif self.prog and not self.match_prog(item['prog']) :
- log.debug("prog: %r", item)
-
- else :
- # ok
- return True
-
def process (self, lines) :
"""
Yield SyslogMessages from given series of lines.
@@ -143,9 +100,8 @@
for line in lines :
item = self.parse(line)
-
- # filter?
- if self.filter(line, item) :
+
+ if item :
yield item
__call__ = process
--- a/pvl/syslog/syslog.py Thu Jan 03 00:38:26 2013 +0200
+++ b/pvl/syslog/syslog.py Thu Jan 03 00:56:28 2013 +0200
@@ -11,12 +11,13 @@
A source of syslog items.
"""
- def __init__ (self, source, parser, poll=None) :
+ def __init__ (self, source, parser, filter=None, poll=None) :
"""
Using given underlying line source.
source - file-like object with poll() and iter()
- parser - process() bytes -> messages
+ parser - process() bytes -> items
+ filter - filter items
poll - using given polling style:
True - select() source
float - given interval
@@ -25,6 +26,7 @@
self.source = source
self.parser = parser
+ self.filter = filter
self._poll = poll
@@ -34,9 +36,17 @@
"""
# directly iter across source
- for item in self.parser(self.source) :
- yield item
+ iter = self.source
+ # parse
+ iter = self.parser(iter)
+
+ # filter ?
+ if self.filter :
+ iter = self.filter(iter)
+
+ return iter
+
def poll (self, timeout=None) :
"""
Poll source for input, with given timeout in seconds (float).