From c0c347cf4a7c3f24b3cb88ef1d6b795bf84e35ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sven=20M=C3=A4der?= <maeder@phys.ethz.ch> Date: Thu, 12 Apr 2018 14:38:51 +0200 Subject: [PATCH] Add input methods to tailer --- bin/deltalogcat.py | 174 ++++++++++++++++++++++++++++++++++++++++++++ bin/deltalogtail.py | 71 ------------------ 2 files changed, 174 insertions(+), 71 deletions(-) create mode 100755 bin/deltalogcat.py delete mode 100755 bin/deltalogtail.py diff --git a/bin/deltalogcat.py b/bin/deltalogcat.py new file mode 100755 index 0000000..47aa1e4 --- /dev/null +++ b/bin/deltalogcat.py @@ -0,0 +1,174 @@ +#!/usr/bin/env python3 + +import sys +import time +import subprocess +import select +import pprint +import json +import argparse +#import base64 +import lib_path +import lib +import dphysldap +import tabulate + +update_every = 0.001 +log_path = '/var/log/ldap/' +log_file_deltalog = log_path + 'delta.log' +indent = 16 + +FMT = 'plain' +tabulate.PRESERVE_WHITESPACE = True + +REQ_ATTRS = frozenset({ + 'reqAuthzID', + 'reqEntryUUID', + 'entryCSN' +}) + +NODES = { + 0: 'phd-aa1', + 1: 'phd-aa2', + 2: 'phd-aa3' +} + + +def getlastline(fname): + """Using mmap to return a copy of the last line of a file""" + with open(fname) as source: + mapping = mmap.mmap(source.fileno(), 0, prot=mmap.PROT_READ) + return mapping[mapping.rfind(b'\n', 0, -1)+1:] + + +def sleep(start_time): + """After hard work, take a nap for the rest of the second""" + current_time = time.perf_counter() + elapsed_time = current_time - start_time + sleep_time = update_every - elapsed_time + + #print('runtime {0:.3f}s, sleeping {1:.3f}s'.format(elapsed_time, sleep_time)) + + if sleep_time > 0: + time.sleep(sleep_time) + + +def parse(line): + """Parse line and print in pretty format""" + req_json = line.split(' >>> ', maxsplit=1)[1] + req = json.loads(req_json) + + sid = int(req['attributes']['entryCSN'][0].split('#')[2]) + + print() + print('{0:<{indent}}{1}'.format('req:', req['dn'], indent=indent)) + print('{0:<{indent}}{1}'.format('node:', NODES[sid], indent=indent)) + print('{0:<{indent}}{1}'.format('changetype:', req['attributes']['reqType'][0], indent=indent)) + print('{0:<{indent}}{1}'.format('entry:', req['attributes']['reqDN'][0], indent=indent)) + + if 'reqMod' in req['attributes']: + table = list() + + for req_mod in req['attributes']['reqMod']: + row = [ ' ' * (indent - 2) ] + row.extend(req_mod.split(' ', maxsplit=1)) + table.append(row) + + print('modfications:') + print(tabulate.tabulate(table, tablefmt=FMT)) + + del req['attributes']['reqMod'] + + entry = dphysldap.Entry(req['attributes']) + table = list() + + for key, value in entry.items(): + if key in REQ_ATTRS: + row = [ ' ' * (indent - 2), ''.join([key, ':']), str(value) ] + table.append(row) + + print('req attrs:') + print(tabulate.tabulate(table, tablefmt=FMT)) + + print() + print('------------------------------------------------------------------------------------------') + + +def get_input_method(arg): + """Determine the input method""" + if arg['follow']: + if arg['file']: + tail_file(arg['file']) + else: + tail_file(log_file_deltalog) + else: + if arg['file']: + read_file(arg['file']) + else: + read_stdin() + + +def tail_file(log_file): + """Open the file in tail mode""" + fin = subprocess.Popen(['tail', '-F', log_file], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + poll = select.poll() + poll.register(fin.stdout) + + while True: + start_time = time.perf_counter() + + if poll.poll(1): + line = fin.stdout.readline().decode('utf-8') + parse(line) + + sleep(start_time) + + +def read_file(log_file): + """Read the whole file""" + with open(log_file, 'r') as fin: + while True: + line = fin.readline() + if not line: + break + parse(line) + + +def read_stdin(): + """Read from stdin""" + fin = sys.stdin + while True: + line = fin.readline() + if not line: + break + parse(line) + + +def main(): + """Open file in non blocking mode and parse json""" + parser = argparse.ArgumentParser(add_help=False, description='Parse deltalog from file or stdin') + parser.add_argument( + '-f', '--follow', + dest='follow', action='store_const', const=True, + help='Output appended data as the file grows' + ) + parser.add_argument( + 'file', + nargs='?', type=str, + help='File to open' + ) + parser.add_argument( + '-h', '--help', + action='help', + help='Show this help message and exit' + ) + arg = vars(parser.parse_args()) + + get_input_method(arg) + + sys.exit(0) + + +if __name__ == '__main__': + main() + sys.exit(0) diff --git a/bin/deltalogtail.py b/bin/deltalogtail.py deleted file mode 100755 index 381ad56..0000000 --- a/bin/deltalogtail.py +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env python3 - -import sys -import time -import subprocess -import select -import pprint -import json -#import base64 - -update_every = 0.001 -log_datefmt = '%Y-%m-%d %H:%M:%S' -log_path = '/var/log/ldap/' -log_file_deltalog = log_path + 'delta.log' - - -def getlastline(fname): - """Using mmap to return a copy of the last line of a file""" - with open(fname) as source: - mapping = mmap.mmap(source.fileno(), 0, prot=mmap.PROT_READ) - return mapping[mapping.rfind(b'\n', 0, -1)+1:] - - -def sleep(start_time): - """After hard work, take a nap for the rest of the second""" - current_time = time.perf_counter() - elapsed_time = current_time - start_time - sleep_time = update_every - elapsed_time - - #print('runtime {0:.3f}s, sleeping {1:.3f}s'.format(elapsed_time, sleep_time)) - - if sleep_time > 0: - time.sleep(sleep_time) - - -def main(): - """Open file in non blocking mode and parse json""" - f = subprocess.Popen(['tail', '-F', log_file_deltalog], stdout=subprocess.PIPE, stderr=subprocess.PIPE) - p = select.poll() - p.register(f.stdout) - - while True: - start_time = time.perf_counter() - - if p.poll(1): - line = f.stdout.readline().decode('utf-8') - req_json = line.split(' >>> ', maxsplit=1)[1] - req = json.loads(req_json) - - print() - print('req: {}'.format(req['dn'])) - print('changetype: {}'.format(req['attributes']['reqType'][0])) - print('entry: {}'.format(req['attributes']['reqDN'][0])) - - if 'reqMod' in req['attributes']: - print('reqMod:') - pprint.pprint(req['attributes']['reqMod'], indent=14) - del req['attributes']['reqMod'] - - print('attributes:') - pprint.pprint(req['attributes'], indent=14) - - print() - print('------------------------------------------------------------------------------------------') - - sleep(start_time) - - -if __name__ == '__main__': - main() - sys.exit(0) -- GitLab