Merge "Add script files of test and spdk-ansible for SPDK"
[stor4nfv.git] / src / ceph / src / tools / histogram_dump.py
1 #!/usr/bin/env python
2 # coding: utf-8
3 #
4 # Ceph - scalable distributed file system
5 #
6 # Copyright (C) 2017 OVH
7 #
8 # This is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU General Public
10 # License version 2, as published by the Free Software
11 # Foundation.  See file COPYING.
12 #
13
14 import json
15 import subprocess
16 import time
17 import os
18 import argparse
19
20
21 def shorten(val):
22     if isinstance(val, str):
23         return val
24     for u in ((3, ''), (6, 'k'), (9, 'M'), (12, 'G'), (15, 'T')):
25         if val < 10**u[0]:
26             return "{}{}".format(int(val / (10 ** (u[0]-3))), u[1])
27     return val
28
29
30 def print_histogram(asok, logger, counter, last):
31
32     try:
33         out = subprocess.check_output(
34             "ceph --admin-daemon {} perf histogram dump".format(asok),
35             shell=True)
36         j = json.loads(out.decode('utf-8'))
37     except Exception as e:
38         return (last,
39                 "Couldn't connect to admin socket, result: \n{}".format(e))
40
41     current = j['osd'][counter]['values']
42     axes = j['osd'][counter]['axes']
43     content = ""
44
45     content += "{}:\n".format(axes[1]['name'])
46     for r in axes[1]['ranges']:
47         content += "{0: >4} ".format(
48             shorten(r['min']) if 'min' in r else '')
49     content += "\n"
50     for r in axes[1]['ranges']:
51         content += "{0: >4} ".format(
52             shorten(r['max']) if 'max' in r else '')
53     content += "\n"
54
55     content += ("{0: >"+str(len(axes[1]['ranges'])*5+14)+"}:\n").format(
56         axes[0]['name'])
57
58     for i in range(len(current)):
59         for j in range(len(current[i])):
60             try:
61                 diff = current[i][j] - last[i][j]
62             except IndexError:
63                 diff = '-'
64             content += "{0: >4} ".format(shorten(diff))
65
66         r = axes[0]['ranges'][i]
67         content += "{0: >6} : {1}\n".format(
68             shorten(r['min']) if 'min' in r else '',
69             shorten(r['max']) if 'max' in r else '')
70     return (current, content)
71
72
73 def loop_print(asok, logger, counter):
74     last = []
75     while True:
76
77         last, content = print_histogram(asok, logger, counter, last)
78         print("{}{}".format("\n"*100, content))
79         time.sleep(1)
80
81
82 def main():
83     parser = argparse.ArgumentParser(
84         description='Continuously display ceph performance histogram')
85     parser.add_argument(
86         '--asok',
87         type=str,
88         default='/var/run/ceph/*.asok',
89         help='Path to asok file, can use wildcards')
90     parser.add_argument(
91         '--logger',
92         type=str,
93         default='osd')
94     parser.add_argument(
95         '--counter',
96         type=str,
97         default='op_w_latency_in_bytes_histogram')
98     args = parser.parse_args()
99
100     loop_print(args.asok, args.logger, args.counter)
101
102
103 if __name__ == '__main__':
104     main()