Ved-vampir | 5c7b614 | 2015-04-24 19:49:59 +0300 | [diff] [blame^] | 1 | """ Analize test results for finding bottlenecks """ |
| 2 | |
| 3 | import sys |
| 4 | import argparse |
| 5 | |
| 6 | import texttable as TT |
| 7 | |
| 8 | from collections import namedtuple |
| 9 | |
| 10 | |
| 11 | Record = namedtuple("Record", ['name', 'max_value']) |
| 12 | |
| 13 | critical_values = [ |
| 14 | Record("io_queue", 1), |
| 15 | Record("procs_blocked", 1), |
| 16 | Record("mem_usage_percent", 0.8) |
| 17 | ] |
| 18 | |
| 19 | def load_results(begin_time, end_time, rfile): |
| 20 | """ Read raw results from dir and return |
| 21 | data from provided period""" |
| 22 | results = {} |
| 23 | |
| 24 | with open(rfile, "r") as f: |
| 25 | for line in f: |
| 26 | |
| 27 | if len(line) <= 1: |
| 28 | continue |
| 29 | ttime, _, raw_data = line.partition(" : ") |
| 30 | raw_data = raw_data.strip('"\n\r') |
| 31 | itime = float(ttime) |
| 32 | if itime >= begin_time and itime <= end_time: |
| 33 | addr, data = eval(raw_data) |
| 34 | sid = data.pop("source_id") |
| 35 | data.pop("time") |
| 36 | serv = "{0}({1})".format(addr[0], sid) |
| 37 | serv_data = results.setdefault(serv, {}) |
| 38 | for key, value in data.items(): |
| 39 | # select device and metric names |
| 40 | dev, _, metric = key.partition(".") |
| 41 | # create dict for metric |
| 42 | metric_dict = serv_data.setdefault(metric, {}) |
| 43 | # set value for metric on dev |
| 44 | cur_val = metric_dict.setdefault(dev, []) |
| 45 | cur_val.append(value) |
| 46 | print results |
| 47 | return results |
| 48 | |
| 49 | |
| 50 | |
| 51 | def print_bottlenecks(data, params): |
| 52 | """ Print bottlenecks in table format, |
| 53 | search in data by fields in params""" |
| 54 | tab = TT.Texttable() |
| 55 | tab.set_deco(tab.VLINES) |
| 56 | |
| 57 | header = ["Server, device", "Critical value"] |
| 58 | tab.add_row(header) |
| 59 | tab.header = header |
| 60 | |
| 61 | rows = [] |
| 62 | val_format = "{0}: {1}, {2} times it was >= {3}" |
| 63 | for node, metrics in data.items(): |
| 64 | node_rows = [] |
| 65 | for metric, max_value in params: |
| 66 | if metric in metrics: |
| 67 | item = metrics[metric] |
| 68 | # find max val for dev |
| 69 | # count times it was > max_value |
| 70 | for dev, vals in item.items(): |
| 71 | num_l = 0 |
| 72 | max_v = -1 |
| 73 | for val in vals: |
| 74 | if val >= max_value: |
| 75 | num_l += 1 |
| 76 | if max_v < val: |
| 77 | max_v = val |
| 78 | if num_l > 0: |
| 79 | c_val = val_format.format(metric, max_v, |
| 80 | num_l, max_value) |
| 81 | node_rows.append([dev, c_val]) |
| 82 | if len(node_rows) > 0: |
| 83 | rows.append([node, ""]) |
| 84 | rows.extend(node_rows) |
| 85 | |
| 86 | for row in rows: |
| 87 | tab.add_row(row) |
| 88 | |
| 89 | print tab.draw() |
| 90 | |
| 91 | |
| 92 | |
| 93 | def parse_args(args): |
| 94 | parser = argparse.ArgumentParser() |
| 95 | parser.add_argument('-t', '--time_period', nargs=2, |
| 96 | type=float, |
| 97 | help="Begin and end time for tests") |
| 98 | parser.add_argument('sensors_result', type=str, |
| 99 | default=None, nargs='?') |
| 100 | return parser.parse_args(args[1:]) |
| 101 | |
| 102 | |
| 103 | def main(argv): |
| 104 | opts = parse_args(argv) |
| 105 | |
| 106 | results = load_results(opts.time_period[0], opts.time_period[1], opts.sensors_result) |
| 107 | |
| 108 | print_bottlenecks(results, critical_values) |
| 109 | |
| 110 | if __name__ == "__main__": |
| 111 | exit(main(sys.argv)) |