From 7d799b85d6644fc1676b21277ce758b5bd313a5b Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Mon, 31 Jul 2017 15:53:32 +0300 Subject: Add: scripts to handle slog files --- slog-errors | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ slog-pretty | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100755 slog-errors create mode 100755 slog-pretty diff --git a/slog-errors b/slog-errors new file mode 100755 index 0000000..920e87d --- /dev/null +++ b/slog-errors @@ -0,0 +1,61 @@ +#!/usr/bin/env python +# +# Read Qvarn structured log files, look for errors, and output all +# messages related to a failed HTTP request (status code 5xx). + + +import json +import sys + + +def parse_log_file(filename): + with open(filename) as f: + for line in f: + yield json.loads(line) + + +def find_contexts(msgs): + return set(get_context(msg) for msg in msgs) + + +def get_context(msg): + return msg['_context'], msg['_process_id'], msg['_thread_id'] + + +def is_in_context(msg, context): + return get_context(msg) == context + + +def filter_msgs(msgs, func): + for msg in msgs: + if func(msg): + yield msg + +def has_error_status(msgs): + for msg in msgs: + if msg['msg_type'] == 'error': + return True + if msg['msg_type'] == 'http-response' and msg['status'] >= 400: + return True + if '_traceback' in msg: + return True + return False + + +def show_msgs(msgs): + sys.stdout.write(json.dumps(msgs)) + sys.stdout.write('\n') + + +msgs = [] +for filename in sys.argv[1:]: + for msg in parse_log_file(filename): + msg['_filename'] = filename + msgs.append(msg) + + +contexts = find_contexts(msgs) +for context in contexts: + context_msgs = list(filter_msgs(msgs, lambda m: is_in_context(m, context))) + if has_error_status(context_msgs): + show_msgs(context_msgs) diff --git a/slog-pretty b/slog-pretty new file mode 100755 index 0000000..80f07fb --- /dev/null +++ b/slog-pretty @@ -0,0 +1,33 @@ +#!/usr/bin/env python + +import json +import sys + +import yaml + + +def text_representer(dumper, data): + if '\n' in data: + return dumper.represent_scalar( + u'tag:yaml.org,2002:str', data, style='|') + return dumper.represent_scalar( + u'tag:yaml.org,2002:str', data, style='') + +yaml.add_representer(str, text_representer) +yaml.add_representer(unicode, text_representer) + + +def dump(f): + for line in f: + obj = json.loads(line.strip()) + yaml.dump( + obj, stream=sys.stdout, indent=4, default_flow_style=False, + explicit_start=True, explicit_end=True) + + +if len(sys.argv) == 1: + dump(sys.stdin) +else: + for filename in sys.argv[1:]: + with open(filename) as f: + dump(f) -- cgit v1.2.1