-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathespr.py
executable file
·115 lines (87 loc) · 2.67 KB
/
espr.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/usr/bin/env python
import argparse
import json
import sys
class ParseException(Exception):
def __init__(self, message):
self.message = message
def __repr__(self):
print(self.message)
def parse_stdin(data):
try:
stdin = json.loads(data)
except ValueError:
raise ParseException('Unable to parse JSON')
try:
by_shard = stdin['profile']['shards']
except KeyError:
raise ParseException('stdin does not contain profile info')
return by_shard
def tree_to_list(head):
# simple stack based dfs to create a
# printable list, nothing fancy
stack = [(head, 0)]
nodes = []
while stack:
cur = stack.pop()
node = cur[0]
depth = cur[1]
# extract attributes along with
# depth attribute
processed_node = {
'depth': depth,
}
processed_node.update(node)
nodes.append(processed_node)
children = node.get('children')
if children:
for c in children:
stack.append((c, depth+1))
return nodes
def print_node(node, verbose=False):
INDENT = ' '
depth = node.get('depth', 0)
print('{}> {} {} ms'.format(
depth*INDENT,
node.get('type'),
int(node.get('time_in_nanos'))/1000
))
# optional breakdown
breakdown = node.get('breakdown')
if verbose and breakdown:
for key, value in breakdown.items():
print('{} {}: {}'.format(
(depth)*INDENT,
key,
value
))
def display(by_shard, verbose=False):
for s in by_shard:
print('Shard: {0}'.format(s.get('id')))
searches = s.get('searches')
if searches:
for s in searches:
# don't care about other queries now
# just trying this out
for q in s['query']:
ordered_nodes = tree_to_list(q)
for n in ordered_nodes:
print_node(n, verbose=verbose)
aggregations = s.get('aggregations')
if aggregations:
for a in aggregations:
ordered_nodes = tree_to_list(a)
for n in ordered_nodes:
print_node(n, verbose=verbose)
print('')
def main():
argparser = argparse.ArgumentParser(description='Process ES profile output.')
argparser.add_argument('--verbose', '-v', action='count')
args = argparser.parse_args()
try:
parsed = parse_stdin(sys.stdin.read())
except ParseException as err:
print(err.message)
display(parsed, args.verbose)
if __name__ == "__main__":
main()