pvl/syslog/syslog.py
author Tero Marttila <terom@fixme.fi>
Fri, 04 Jan 2013 14:19:05 +0200
changeset 48 40ccb8d3c96e
parent 44 977442ccb72d
child 50 0bbe2e7561a1
permissions -rw-r--r--
pvl.verkko-syslog: syslog -> irker gateway
"""
    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()