~marcobiscaro2112/unity/fixes-724739

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()