44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
1 |
#!/usr/bin/env python
|
2 |
#
|
|
3 |
# Copyright (C) 2009 Canonical Ltd
|
|
4 |
#
|
|
5 |
# This program is free software: you can redistribute it and/or modify
|
|
6 |
# it under the terms of the GNU General Public License version 3 as
|
|
7 |
# published by the Free Software Foundation.
|
|
8 |
#
|
|
9 |
# This program is distributed in the hope that it will be useful,
|
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12 |
# GNU General Public License for more details.
|
|
13 |
#
|
|
14 |
# You should have received a copy of the GNU General Public License
|
|
15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
16 |
#
|
|
17 |
# Authored by Gordon Allott <gord.allott@canonical.com>
|
|
18 |
#
|
|
19 |
#
|
|
20 |
import os, sys |
|
21 |
import getopt |
|
22 |
import cairo |
|
23 |
import csv |
|
24 |
import math |
|
25 |
import random |
|
26 |
from string import Template |
|
636.8.1
by Gord Allott
perf logger update |
27 |
from socket import gethostname |
28 |
from datetime import datetime |
|
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
29 |
import re |
30 |
import subprocess |
|
31 |
||
32 |
header = Template("""Unity bootchart for $hostname ($date) |
|
33 |
uname: $uname
|
|
34 |
CPU: $cpu
|
|
35 |
GPU: $gpu
|
|
36 |
time: $total_time""") |
|
37 |
||
38 |
def sort_by_domain (x, y): |
|
44.1.8
by Gordon Allott
updated configure file, added new logging function for even smaller statements (only for functions that get called once) |
39 |
if x["start"] - y["start"] < 0: |
44.1.2
by Gordon Allott
few fixes and added places monitoring |
40 |
return -1 |
44.1.8
by Gordon Allott
updated configure file, added new logging function for even smaller statements (only for functions that get called once) |
41 |
else: |
636.8.1
by Gord Allott
perf logger update |
42 |
return +1 |
43 |
||
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
44 |
def gatherinfo (filename): |
45 |
date = datetime.fromtimestamp(os.path.getmtime(filename)) |
|
636.8.1
by Gord Allott
perf logger update |
46 |
|
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
47 |
cpufile = open ("/proc/cpuinfo") |
48 |
cpuinfo = cpufile.read (10024) |
|
49 |
cpure = re.search (r"^model name\s*: (.*$)", cpuinfo, re.MULTILINE) |
|
50 |
cpu = cpure.group(1) |
|
636.8.1
by Gord Allott
perf logger update |
51 |
|
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
52 |
gpu_prog = subprocess.Popen("glxinfo", stdout=subprocess.PIPE) |
636.8.1
by Gord Allott
perf logger update |
53 |
gpu_prog.wait () |
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
54 |
gpuinfo = gpu_prog.stdout.read (10024) |
55 |
gpure = re.search (r"^OpenGL renderer string: (.*$)", gpuinfo, re.MULTILINE) |
|
56 |
gpu = gpure.group (1) |
|
636.8.1
by Gord Allott
perf logger update |
57 |
|
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
58 |
return {"hostname":gethostname(), |
59 |
"date": date.strftime("%A, %d. %B %Y %I:%M%p"), |
|
60 |
"uname": " ".join (os.uname ()), |
|
61 |
"cpu": cpu, |
|
62 |
"gpu": gpu, |
|
63 |
"total_time": "undefined" |
|
64 |
}
|
|
65 |
||
66 |
width_multiplier = 1000 |
|
67 |
bar_height = 16 |
|
68 |
||
69 |
def draw_bg_graph (ctx, seconds, height): |
|
636.8.1
by Gord Allott
perf logger update |
70 |
|
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
71 |
total_width = seconds * width_multiplier |
72 |
ctx.set_source_rgba (0.0, 0.0, 0.0, 0.25) |
|
636.8.1
by Gord Allott
perf logger update |
73 |
|
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
74 |
ctx.move_to (0, 0) |
75 |
ctx.line_to (total_width, 0) |
|
76 |
ctx.stroke () |
|
636.8.1
by Gord Allott
perf logger update |
77 |
|
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
78 |
per_ten = 0 |
79 |
for pos in xrange (0, int(total_width), int (0.01 * width_multiplier)): |
|
80 |
ctx.set_line_width (1) |
|
81 |
ctx.set_source_rgba (0.0, 0.0, 0.0, 0.10) |
|
82 |
||
83 |
if (not per_ten): |
|
84 |
ctx.set_line_width (2) |
|
85 |
ctx.set_source_rgba (0.0, 0.0, 0.0, 0.25) |
|
86 |
ctx.move_to (pos-6, -2) |
|
87 |
ctx.show_text (str (pos / float(width_multiplier))) |
|
88 |
ctx.stroke () |
|
89 |
||
90 |
ctx.move_to (pos, 0) |
|
91 |
ctx.line_to (pos, height) |
|
92 |
ctx.stroke () |
|
636.8.1
by Gord Allott
perf logger update |
93 |
|
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
94 |
per_ten += 1 |
95 |
per_ten %= 10 |
|
96 |
||
97 |
def build_graph (data, filename, info): |
|
636.8.1
by Gord Allott
perf logger update |
98 |
|
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
99 |
padding_left = 6 |
44.1.2
by Gordon Allott
few fixes and added places monitoring |
100 |
padding_right = 100 |
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
101 |
padding_top = 6 |
102 |
padding_bottom = 6 |
|
636.8.1
by Gord Allott
perf logger update |
103 |
|
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
104 |
total_size = 0.0 |
105 |
for item in data: |
|
106 |
if item['end'] > total_size: |
|
107 |
total_size = item['end'] |
|
636.8.1
by Gord Allott
perf logger update |
108 |
|
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
109 |
width = total_size * width_multiplier + padding_left + padding_right |
44.1.8
by Gordon Allott
updated configure file, added new logging function for even smaller statements (only for functions that get called once) |
110 |
height = (len(data) * (bar_height)) + 80 + padding_bottom + padding_top |
636.8.1
by Gord Allott
perf logger update |
111 |
surface = cairo.SVGSurface(filename, max (width, 800), max (height, 600)) |
112 |
||
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
113 |
ctx = cairo.Context (surface) |
114 |
||
115 |
#fill background
|
|
116 |
ctx.set_source_rgb (1, 1, 1) |
|
636.8.1
by Gord Allott
perf logger update |
117 |
ctx.rectangle (0, 0, max (width, 800), max (height, 600)) |
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
118 |
ctx.fill () |
636.8.1
by Gord Allott
perf logger update |
119 |
|
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
120 |
#print header
|
121 |
info['total_time'] = "%s secs" % total_size |
|
122 |
sheader = header.substitute(info) |
|
636.8.1
by Gord Allott
perf logger update |
123 |
|
44.1.2
by Gordon Allott
few fixes and added places monitoring |
124 |
ctx.translate (padding_left, padding_top) |
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
125 |
ctx.set_source_rgb (0, 0, 0) |
126 |
for line in sheader.split("\n"): |
|
127 |
ctx.translate (0, 12) |
|
128 |
ctx.show_text (line) |
|
129 |
ctx.fill () |
|
636.8.1
by Gord Allott
perf logger update |
130 |
|
131 |
ctx.translate (6, 12) |
|
132 |
||
133 |
draw_bg_graph (ctx, total_size + 0.5, max (len (data) * bar_height + 64, 500)) |
|
134 |
||
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
135 |
ctx.set_line_width (1) |
136 |
for item in data: |
|
137 |
x = item['start'] * width_multiplier |
|
138 |
x1 = (item['end'] - item['start']) * width_multiplier |
|
139 |
ctx.translate (x, 0) |
|
636.8.1
by Gord Allott
perf logger update |
140 |
|
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
141 |
ctx.set_source_rgba (0.35, 0.65, 0.8, 0.5) |
142 |
ctx.rectangle (0, 0, x1, 16) |
|
143 |
ctx.fill () |
|
636.8.1
by Gord Allott
perf logger update |
144 |
|
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
145 |
ctx.set_source_rgba (0.35, 0.65, 0.8, 1.0) |
146 |
ctx.rectangle (0, 0, x1, 16) |
|
147 |
ctx.stroke () |
|
636.8.1
by Gord Allott
perf logger update |
148 |
|
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
149 |
ctx.translate (8, 10) |
150 |
ctx.set_source_rgb (0.0, 0.0, 0.0) |
|
636.8.1
by Gord Allott
perf logger update |
151 |
ctx.show_text ("%s %.4f seconds" % (item['name'], item["end"] - item["start"])) |
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
152 |
ctx.fill() |
636.8.1
by Gord Allott
perf logger update |
153 |
|
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
154 |
ctx.translate (-x-8, 6) |
155 |
||
156 |
def build_data_structure (input): |
|
157 |
reader = csv.reader(open(input)) |
|
158 |
structure = [] |
|
159 |
print "reading", input |
|
160 |
for row in reader: |
|
161 |
name = row[0] |
|
162 |
start = float(row[1]) |
|
163 |
end = float(row[2]) |
|
164 |
structure.append ({"name": name, "start": start, "end": end}) |
|
636.8.1
by Gord Allott
perf logger update |
165 |
|
44.1.2
by Gordon Allott
few fixes and added places monitoring |
166 |
structure.sort (sort_by_domain) |
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
167 |
return structure |
636.8.1
by Gord Allott
perf logger update |
168 |
|
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
169 |
|
170 |
def usage(): |
|
636.8.1
by Gord Allott
perf logger update |
171 |
print "use --input=filename.log and --output=filename.svg :)" |
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
172 |
|
173 |
def main(): |
|
174 |
||
175 |
try: |
|
176 |
opts, args = getopt.getopt(sys.argv[1:], "h", ["help", "output=", "input="]) |
|
177 |
except getopt.GetoptError, err: |
|
178 |
# print help information and exit:
|
|
179 |
print str(err) # will print something like "option -a not recognized" |
|
180 |
usage() |
|
181 |
sys.exit(2) |
|
636.8.1
by Gord Allott
perf logger update |
182 |
|
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
183 |
output = None |
184 |
input = None |
|
185 |
for o, a in opts: |
|
186 |
if o in ("-h", "--help"): |
|
187 |
usage() |
|
188 |
sys.exit() |
|
189 |
elif o in ("--output"): |
|
190 |
output = a |
|
191 |
elif o in ("--input"): |
|
192 |
input = a |
|
193 |
else: |
|
194 |
assert False, "unhandled option" |
|
195 |
||
196 |
if (not output or not input): |
|
197 |
usage() |
|
198 |
sys.exit() |
|
636.8.1
by Gord Allott
perf logger update |
199 |
|
44.1.1
by Gordon Allott
performance logger support and boot chart generation script |
200 |
data = build_data_structure (input) |
201 |
info = gatherinfo (input) |
|
202 |
build_graph (data, output, info) |
|
203 |
||
204 |
||
205 |
return 0 |
|
206 |
||
207 |
if __name__ == '__main__': main() |