OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/python |
| 2 ''' |
| 3 Translate trace data to json for visualizing it with D3js. |
| 4 Usage: |
| 5 # perf script | ./d3trace.py > trace_json.js |
| 6 |
| 7 Copyright (C) 2013 Eiichi Tsukata <devel@etsukata.com> |
| 8 ''' |
| 9 |
| 10 |
| 11 import sys |
| 12 import re |
| 13 |
| 14 def stack_sample_to_dict(sample): |
| 15 |
| 16 ret = {} |
| 17 |
| 18 if len(sample['stack_trace']) == 1: |
| 19 ret['name'] = sample['stack_trace'][0] |
| 20 ret['size'] = sample['count'] |
| 21 return ret |
| 22 |
| 23 ret['name'] = sample['stack_trace'][0] |
| 24 tail_stack = sample['stack_trace'][1:] |
| 25 ret['children'] = [stack_sample_to_dict({ |
| 26 'stack_trace' : tail_stack, |
| 27 'count' : sample['count'] |
| 28 })] |
| 29 return ret |
| 30 |
| 31 def add_root(child): |
| 32 |
| 33 ret = { |
| 34 'name' : 'All', |
| 35 'children' : [child] |
| 36 } |
| 37 return ret |
| 38 |
| 39 def merge_dict(d1, d2): |
| 40 |
| 41 def has_same_child(d1, d2): |
| 42 for d in d1['children']: |
| 43 if d['name'] == d2['children'][0]['name']: |
| 44 return True |
| 45 return False |
| 46 |
| 47 if not d1['name'] == d2['name']: |
| 48 print 'error on merge_dict(): root is not same.' |
| 49 print 'd1:' |
| 50 print(d1) |
| 51 print 'd2:' |
| 52 print(d2) |
| 53 sys.exit(1) |
| 54 |
| 55 if not d1.has_key('children'): |
| 56 return merge_dict(d2, d1) |
| 57 |
| 58 ret = d1.copy() |
| 59 |
| 60 if d2.has_key('children'): |
| 61 if has_same_child(ret, d2): |
| 62 children = ret['children'] |
| 63 for i in range(0, len(children)): |
| 64 if children[i]['name'] == d2['children'][0]['name']: |
| 65 children[i] = merge_dict(children[i], d2['children'][0]) |
| 66 else: |
| 67 ret['children'].append(d2['children'][0]) |
| 68 else: |
| 69 dummy = { |
| 70 'name' : '', |
| 71 'size' : d2['size'] |
| 72 } |
| 73 ret['children'].append(dummy) |
| 74 |
| 75 return ret |
| 76 |
| 77 def strip_func(f): |
| 78 |
| 79 ret = f |
| 80 ret = re.sub(r'\(\[kernel.kallsyms\]\.init\.text\)', '', ret) |
| 81 ret = re.sub(r'\(\[kernel.kallsyms\]\)', '', ret) |
| 82 ret = re.sub(r'\(\[unknown\]\)', '', ret) |
| 83 ret = re.sub(r'\(\)', '', ret) |
| 84 ret = ''.join(ret.split()[1:]) |
| 85 return ret |
| 86 |
| 87 def main(input_text=None): |
| 88 |
| 89 if input_text is None: |
| 90 input_text = sys.stdin |
| 91 |
| 92 stack_traces = [] |
| 93 stack_trace = [] |
| 94 stack_samples = [] |
| 95 |
| 96 for line in input_text: |
| 97 if line[0] == '#': |
| 98 continue |
| 99 if line[0] == '\n': |
| 100 if not stack_trace == []: |
| 101 stack_traces.append(stack_trace) |
| 102 stack_trace = [] |
| 103 continue |
| 104 if line[0] == '\t': |
| 105 stack_trace.append(line.strip()) |
| 106 continue |
| 107 |
| 108 for st in stack_traces: |
| 109 count = stack_traces.count(st) + 1 |
| 110 st.reverse() |
| 111 st = [strip_func(x) for x in st] |
| 112 stack_sample = { |
| 113 'stack_trace' : st, |
| 114 'count' : count |
| 115 } |
| 116 if not st in [x['stack_trace'] for x in stack_samples]: |
| 117 stack_samples.append(stack_sample) |
| 118 |
| 119 root = { |
| 120 'name' : 'All', |
| 121 'children' : [] |
| 122 } |
| 123 |
| 124 for ss in stack_samples: |
| 125 dict_data = stack_sample_to_dict(ss) |
| 126 dict_data = add_root(dict_data) |
| 127 root = merge_dict(root, dict_data) |
| 128 |
| 129 return "var trace_json = " + str(root) |
| 130 |
| 131 if __name__ == '__main__': |
| 132 output = main() |
| 133 print output |
OLD | NEW |