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