pvl/syslog/args.py
author Tero Marttila <terom@paivola.fi>
Sun, 13 Jan 2013 02:43:38 +0200
changeset 123 f35b2940b7fc
parent 114 2e88e1d8e604
child 146 6c0ebd37d334
permissions -rw-r--r--
pvl.syslog.args: implement --syslog-stdin using pvl.syslog.fifo.Pipe, lets us read from stdin without blocking
import optparse, sys

from pvl.syslog.parser import SyslogParser
from pvl.syslog.filter import SyslogFilter
from pvl.syslog.syslog import SyslogSource
from pvl.syslog import fifo, tail, file

# XXX: use optparse parser.error()?
import logging; log = logging.getLogger('pvl.syslog.args')

def parser (parser, prog=None) :
    """
        Optparse option group

            prog        - filter to only process lines from given process
    """
    
    syslog = optparse.OptionGroup(parser, 'Syslog collector')

    syslog.add_option('--syslog-fifo',          metavar='PATH',
            help="Read syslog messages from given fifo")

    syslog.add_option('--syslog-file',          metavar='FILE',
            help="Read syslog messages from given file")

    syslog.add_option('--syslog-tail',          metavar='FILE',
            help="Continuously poll syslog messages given file")

    syslog.add_option('--syslog-stdin',         action='store_true',
            help="Read syslog messages from stdin")

    syslog.add_option('--syslog-raw',           action='store_true',
            help="Parse raw syslog lines without timestamp/etc")

    syslog.add_option('--syslog-facility',      metavar='FACILITY',
            help="Set/filter by given facility")

    syslog.add_option('--syslog-severity',      metavar='SEVERITY',
            help="Set given facility")

    syslog.add_option('--syslog-prog',          metavar='PROG',     default=prog,
            help="Filter by given prog: %default")

    return syslog

def apply (options, optional=False) :
    """
        Handle options, returning a SyslogSource, if any.

        May log.error/sys.exit
    """
    
    # XXX: this belongs in pvl.syslog.source
    if options.syslog_fifo :
        # fifo pipe
        source = fifo.Fifo(options.syslog_fifo)
        poll = True # select(source)

    elif options.syslog_tail :
        # tail file
        source = tail.Tail(options.syslog_tail, skip=True)
        poll = tail.Tail.POLL # select(float)

    elif options.syslog_file :
        # read file
        source = file.File(open(options.syslog_file))
        poll = False # do not loop, just read up to EOF

    elif options.syslog_stdin :
        # read pipe
        source = fifo.Pipe.file(sys.stdin) # puts stdin into non-blocking mode
        poll = True # select(source)

    elif optional :
        return None

    else :
        # from stdin
        if sys.stdin.isatty() :
            log.warning("Reading syslog messages from TTY?")
        
        source = file.File(sys.stdin)
        poll = False # XXX: tty vs pipe vs file? False -> just block
    
    # options
    parser = SyslogParser(
        raw         = options.syslog_raw,
        facility    = options.syslog_facility,
        severity    = options.syslog_severity,
    )

    filter = SyslogFilter(
        # glob pattern
        prog        = options.syslog_prog,
        facility    = options.syslog_facility,
        #severity   = options.sylog_severity,   # XXX: match as greater-than?
    )

    # polling
    return SyslogSource(source, parser, filter, poll)