pvl/syslog/syslog.py
author Tero Marttila <terom@fixme.fi>
Fri, 04 Jan 2013 18:44:58 +0200
changeset 50 0bbe2e7561a1
parent 48 40ccb8d3c96e
child 60 9326ed989645
permissions -rw-r--r--
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