"""
Syslog handling.
"""
import select
import logging; log = logging.getLogger('pvl.syslog.source')
class SyslogSource (object) :
"""
A source of syslog items.
"""
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 -> items
filter - filter items
poll - using given polling style:
True - select() source
float - given interval
None/False - single-shot
"""
self.source = source
self.parser = parser
self.filter = filter
log.debug("source: %s", source)
self._poll = poll
def __iter__ (self) :
"""
Read syslog messages from source.
"""
# directly iter across source
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).
A timeout of None indicates to block forever, False indicates to never block.
Returns True if we have input waiting, False on timeout with no input. None on indeterminate.
"""
read = write = ()
if timeout is True :
timeout = None
read += (self.source, )
elif timeout is False :
timeout = 0.0
log.debug("%s", timeout)
# select
read, write, ex = select.select(read, write, [], timeout)
if read :
return True
else :
# timeout
return False
def loop (self) :
"""
Continuously read items from syslog source, blocking as suitable.
Returns once no more lines are available.
XXX: reconnect?
"""
# mainloop
while True :
log.debug("tick")
# pull in messages
for item in self :
log.debug("%s", item)
yield item
# poll
if self._poll :
# wait
self.poll(self._poll)
else :
# done
break
log.debug("exit")
def stop (self) :
"""
Stop loop after current iteration.
"""
self._poll = False
def main (self) :
"""
Mainloop.
"""
# TODO: SIGINT -> stop()
return loop()