terom@43: #!/usr/bin/env python terom@43: terom@43: """ terom@48: Syslog -> Irk terom@43: """ terom@43: terom@43: __version__ = '0.0' terom@43: terom@43: import pvl.args terom@43: import pvl.syslog.args terom@48: import pvl.syslog.rule terom@80: import pvl.irk terom@43: terom@43: import logging, optparse terom@43: terom@43: log = logging.getLogger('main') terom@43: terom@43: def parse_options (argv) : terom@43: """ terom@43: Parse command-line arguments. terom@43: """ terom@43: terom@43: prog = argv[0] terom@43: terom@43: parser = optparse.OptionParser( terom@43: prog = prog, terom@43: usage = '%prog: [options]', terom@43: version = __version__, terom@43: terom@43: # module docstring terom@43: description = __doc__, terom@43: ) terom@43: terom@43: # options terom@43: parser.add_option_group(pvl.args.parser(parser)) terom@48: terom@48: # input terom@43: parser.add_option_group(pvl.syslog.args.parser(parser)) terom@51: parser.add_option_group(pvl.syslog.rule.parser(parser)) terom@82: parser.add_option_group(pvl.irk.parser(parser, connect=None)) terom@43: terom@76: parser.add_option('--irker-target', metavar='IRC', terom@76: help="Irker target URL") terom@76: terom@43: # parse terom@43: options, args = parser.parse_args(argv[1:]) terom@43: terom@43: # apply terom@96: pvl.args.apply(options, prog, rootok=False) terom@43: terom@43: return options, args terom@43: terom@126: def apply_irker (irker) : terom@126: """ terom@126: Handle irker activity. terom@126: """ terom@126: terom@126: for msg in irker.irk : terom@126: log.info("irk: %s", msg) terom@126: terom@126: def apply_syslog (options, syslog, rules, irker) : terom@126: """ terom@126: Handle syslog activity. terom@126: """ terom@126: terom@126: # syslogs terom@126: for item in syslog : terom@126: match, rulepath, apply = rules.apply(item) terom@126: terom@126: log.debug("%s: %s: %s", item, rulepath, apply) terom@126: terom@126: target = apply.get('irk', options.irker_target) terom@126: terom@126: tag = '/'.join(str(rule) for rule in reversed(rulepath[:-1])) terom@126: text = apply.get('text') terom@126: terom@126: log.info("%s: %s: %s", target, tag, text) terom@126: terom@126: if not text : terom@126: # XXX: plain irk = ... in rule is broken, as it always applies, and skips any further rules terom@126: continue terom@126: terom@126: if irker and target : terom@126: irker[target]('[' + tag + '] ' + text) terom@126: else : terom@126: print tag, text terom@126: terom@140: def close_irker (irker) : terom@129: """ terom@129: Shutdown irker before quitting. terom@140: terom@140: XXX: irker.close() to disconnect? terom@129: """ terom@129: terom@129: log.info("Shutting down IRK...") terom@129: terom@129: for target in list(irker) : terom@129: log.warn("%s", target) terom@129: del irker[target] terom@129: terom@140: def close_syslog (syslog) : terom@140: """ terom@140: Shutdown syslog before quitting terom@140: """ terom@140: terom@140: # XXX: do all sources support close()? terom@140: log.warn("%s", syslog) terom@140: syslog.close() terom@140: terom@43: def main (argv) : terom@43: options, args = parse_options(argv) terom@126: terom@126: # no args terom@48: if args : terom@126: log.error("Usage: pvl.irker-syslog [options]") terom@126: return 2 terom@43: terom@126: # setup terom@48: log.info("Open syslog...") terom@43: syslog = pvl.syslog.args.apply(options) terom@51: terom@48: log.info("Load rules...") terom@51: rules = pvl.syslog.rule.apply(options) terom@48: terom@48: log.info("Connect IRK..") terom@80: irker = pvl.irk.apply(options) terom@89: terom@89: if options.irker_target : terom@89: # pre-join target terom@89: irker[options.irker_target] terom@48: terom@48: log.info("Process syslog messages...") terom@113: terom@113: # customized mainloop that supports irker.irk terom@113: while True : terom@126: try : terom@133: # TODO: seprate IrkError, to not confuse irk write vs syslog read eof terom@126: apply_syslog(options, syslog, rules, irker) terom@113: terom@126: except EOFError as ex : terom@126: log.error("syslog: EOF") terom@140: terom@140: close_irker(irker) terom@140: terom@140: # 0 is controlled exit terom@131: return 0 terom@115: terom@145: except pvl.irk.IrkError as ex : terom@145: log.error("irker: %s", ex) terom@145: terom@145: # XXX: copy-pasta terom@145: close_syslog(syslog) terom@145: return 0 terom@145: terom@121: # quit unless we have something to poll terom@121: if not syslog.poll : terom@115: break terom@119: terom@121: # is irk pollable? terom@121: if irker.irk.recv : terom@121: reading = (irker.irk, ) terom@121: else : terom@121: reading = () terom@121: terom@121: poll = syslog.select(syslog.poll, reading=reading) or () # timeout -> () terom@121: terom@121: if irker.irk in poll : terom@121: # irks? terom@121: try : terom@126: apply_irker(irker) terom@119: terom@121: except EOFError : terom@140: log.error("irk: EOF") terom@140: terom@140: close_syslog(syslog) terom@140: terom@131: # exit 0, so as to restart sooner terom@131: # XXX: maybe use a special exit code instead? terom@131: return 0 terom@126: terom@43: # done terom@43: log.info("Exiting...") terom@43: return 0 terom@43: terom@43: if __name__ == '__main__': terom@43: import sys terom@43: terom@43: sys.exit(main(sys.argv))