pvl.syslog: simplify SyslogSource, and implement better handling for sys.stdin using tail.Tail
"""
Syslog handling.
"""
import select
import logging; log = logging.getLogger('pvl.syslog.source')
class SyslogSource (object) :
"""
Process syslog input from a given source.
Implements an iterable mainloop doing continuous polling on the source, using either a timeout or
select():able source.
"""
def __init__ (self, syslog, source, poll=None) :
"""
Using given underlying line source.
syslog - iterable
source - source to select() if poll=True
poll - polling behaviour
"""
self.syslog = syslog
self.source = source
self._poll = poll
def poll (self, poll=None) :
"""
Poll our source for input, with given polling behaviour:
True - select() on source
False - peek on source
float - timeout in seconds
Returns True if we have input waiting, False on timeout with no input. None on indeterminate.
"""
reading = writing = ()
if poll is True :
timeout = None # block
reading += (self.source, ) # file-like object with fileno()
elif not poll :
timeout = 0.0 # do not block
else :
timeout = float(poll)
log.debug("%s", timeout)
# select
readable, writeable, ex = select.select(reading, writing, [], timeout)
if readable :
return True
elif reading :
# timeout
return False
else :
# unknown
return None
def main (self, poll=None) :
"""
yield items from syslog source, polling as given.
Returns once no more lines are available.
XXX: reconnect? or source takes care of that..
TODO: SIGINT -> finish iteration and return?
"""
if poll is None :
poll = self._poll
# mainloop
while True :
# pull in messages
for item in self.syslog :
log.debug("%s", item)
yield item
# poll
if poll :
# wait
self.poll(poll)
else :
# done
break
log.debug("exit")
__iter__ = main