| #!/usr/bin/python |
| |
| import pdb |
| import argparse |
| import sys |
| from pyparsing import * |
| import json |
| import os |
| import patterns |
| import json |
| import logging |
| import logstash |
| import time |
| |
| def follow(thefile): |
| while True: |
| line = thefile.readline() |
| if not line: |
| time.sleep(0.1) |
| continue |
| yield line |
| |
| |
| parse = argparse.ArgumentParser(description='Convert log file to json.') |
| parse.add_argument('--format', dest='format', action='store',default=None, help='Format e.g. Ansible') |
| parse.add_argument('--hostport', dest='hostport', action='store',default=None, help='Logstash UDP host:port') |
| parse.add_argument('--file', dest='filename', action='store',default=None, help='Filename to follow') |
| |
| args = parse.parse_args() |
| |
| host,port = args.hostport.split(':') |
| |
| format = args.format |
| |
| logger = logging.getLogger('python-logstash-logger') |
| logger.setLevel(logging.INFO) |
| logger.addHandler(logstash.LogstashHandler(host, int(port), version=1)) |
| |
| def send_log(log): |
| |
| try: |
| msg = log['desc'] |
| except KeyError: |
| msg = 'Metadata' |
| |
| time.sleep(0.1) |
| try: |
| logger.info(msg, extra=log) |
| except Exception,e: |
| logger.info('Logstash log failed', extra={'xos_fatal':1,'exception':str(e)}) |
| pass |
| |
| ### Read parser from patterns.py |
| |
| def extract_global(l): |
| g = None |
| |
| try: |
| global_tag = "==>" + Word(alphanums) + ":" + SkipTo(LineEnd(),include=True) |
| s = global_tag.parseString(l) |
| l = s[3]+'\n' |
| g = s[1] |
| except: |
| pass |
| |
| return g,l |
| |
| def serialize_raw(s): |
| for l in s.splitlines(): |
| g,l = extract_global(l) |
| report(l, g) |
| |
| def report(payload,g): |
| if (not payload): |
| return |
| |
| if (type(payload)!=dict): |
| payload = {'desc':payload, 'global_tag': g} |
| |
| send_log(payload) |
| #print payload |
| |
| def run_logger(): |
| lst = [] |
| for n in dir(patterns.Parser): |
| sym = getattr(patterns.Parser, n) |
| if isinstance(sym,ParserElement): |
| lst.append(sym) |
| |
| default = SkipTo(LineEnd(),include=True) |
| |
| xos_logger = Or(lst) |
| |
| inp = '' |
| lc = 0 |
| |
| if (args.filename): |
| source = follow(open(args.filename)) |
| |
| while True: |
| if (not args.filename): |
| l = sys.stdin.readline() |
| else: |
| l = source.next() |
| |
| if (l==""): |
| break |
| elif len(l)>200: |
| continue |
| |
| inp += l |
| lc = len(inp.split('\n')) |
| |
| if (lc>4): |
| top = inp.splitlines()[0] |
| try: |
| line_idx = inp.index('\n') |
| inp=inp[line_idx+1:] |
| |
| g,top = extract_global(top) |
| report(top,g) |
| lc = len(inp.split('\n')) |
| except ValueError: |
| pass |
| |
| try: |
| s = xos_logger.scanString(inp) |
| |
| last = None |
| first = True |
| for i in s: |
| |
| if (first): |
| pending = inp[:i[1]] |
| serialize_raw(pending) |
| |
| first = False |
| |
| try: |
| payload = i[0][0] |
| g,_ = extract_global(inp) |
| report(payload,g) |
| except IndexError: |
| pass |
| |
| last = i |
| |
| if (last): |
| inp = inp[last[2]:] |
| lines = inp.splitlines() |
| lc=len(lines) |
| |
| except Exception,e: |
| # We don't want logging to hold up execution |
| #print str(e) |
| pass |
| |
| def main(): |
| run_logger() |
| |
| |
| if __name__ == "__main__": |
| main() |