Skip to content

Instantly share code, notes, and snippets.

@sesam
Created April 10, 2010 23:41
Show Gist options
  • Save sesam/362374 to your computer and use it in GitHub Desktop.
Save sesam/362374 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
import os
import sys
import cairo
SSD_HOST = "max"
HDD_HOST = "sam"
BOOTCHARTS = "public_html/daily-bootcharts"
INSTALLER = "public_html/daily-installer"
POINTS = ['boot', 'kernel', 'plumbing', 'xorg', 'desktop', 'kernelinit']
CAPTIONS = {
'boot': 'Boot Time',
'kernel': 'Kernel',
'plumbing': 'Plumbing',
'xorg': 'X.org',
'desktop': 'Desktop',
'kernelinit': 'Kernel Init'
}
def main(dates):
start = min(int(float(date)) for date in dates)
end = max(int(float(date)) for date in dates)
all_dates = []
for day in range(end, start-1, -1):
year = day / 10000
month = day % 10000 / 100
dom = day % 100
if month > 12:
continue
elif month in (1, 3, 5, 7, 8, 10, 12):
if dom > 31:
continue
elif month in (2, 4, 6, 9, 11):
if dom > 30:
continue
elif (year % 4 == 0) and ((year % 100 != 0) or (year % 400 == 0)):
if dom > 29:
continue
else:
if dom > 28:
continue
today = [ date for date in dates if int(float(date))==day ]
if len(today):
today.reverse()
all_dates.extend(today)
else:
all_dates.append(str(day))
f = open("%s/index.html" % BOOTCHARTS, "w")
try:
include(f, "header.html", {'title': "Daily bootcharts" })
include(f, "bootcharts.html")
times = {}
for host in (SSD_HOST,HDD_HOST):
times[host] = {}
for point in POINTS:
times[host][point] = []
for point in POINTS:
print >>f, "<img src=\"%s.svg\">" % point
print >>f, "<table>"
print >>f, "<tr>"
print >>f, "<th rowspan=\"2\"></th>"
print >>f, "<th colspan=\"6\" class=\"mast\">%s (SSD)</th>" % SSD_HOST
print >>f, "<th colspan=\"6\" class=\"mast\">%s (HDD)</th>" % HDD_HOST
print >>f, "</tr>"
print >>f, "<tr>"
for point in POINTS:
print >>f, "<th class=\"%s\">%s</th>" % (point, CAPTIONS[point])
for point in POINTS:
print >>f, "<th class=\"%s\">%s</th>" % (point, CAPTIONS[point])
print >>f, "</tr>"
for date in all_dates:
print >>f, "<tr>"
if date in dates:
print >>f, "<th rowspan=\"2\">%s</th>" % date
for host in (SSD_HOST, HDD_HOST):
if not os.path.isfile("%s/%s-%s.times" % (BOOTCHARTS, date, host)):
print >>f, "<td rowspan=\"2\" colspan=\"6\"></td>"
continue
t = open("%s/%s-%s.times" % (BOOTCHARTS, date, host))
try:
try:
boot_time = float(t.readline()) / 100
print >>f, "<td class=\"%s\">%.2fs</td>" % (POINTS[0],boot_time)
times[host][POINTS[0]].append((date, boot_time))
except ValueError:
print >>f, "<td class=\"%s\"></td>" % point
boot_time = 0.0
last = 0.0
for point in POINTS[1:-2]:
try:
time = float(t.readline()) / 100
times[host][point].append((date, time-last))
print >>f, "<td class=\"%s\">%.2fs</td>" % (point, time-last)
last = time
except ValueError:
print >>f, "<td class=\"%s\"></td>" % point
times[host][POINTS[-2]].append((date, boot_time-last))
print >>f, "<td class=\"%s\">%.2fs</td>" % (POINTS[-2],boot_time-last)
try:
kernel_time = float(t.readline()) / 100
times[host][POINTS[-1]].append((date, kernel_time))
print >>f, "<td class=\"%s\">%.2fs</td>" % (POINTS[-1],kernel_time)
except ValueError:
print >>f, "<td class=\"%s\"></td>" % point
finally:
t.close()
print >>f, "</tr>"
print >>f, "<tr>"
for host in (SSD_HOST, HDD_HOST):
if not os.path.isfile("%s/%s-%s.times" % (BOOTCHARTS, date, host)):
continue
print >>f, "<td colspan=\"6\">"
print >>f, "<a href=\"%s-%s.png\">bootchart</a>" % (date, host)
print >>f, "<a href=\"%s-%s-kernel.png\">kernel</a>" % (date, host)
print >>f, "<a href=\"%s-%s.dmesg\">dmesg</a>" % (date, host)
print >>f, "</td>"
else:
print >>f, "<th>%s</th>" % date
print >>f, "<td colspan=\"6\"></td>"
print >>f, "<td colspan=\"6\"></td>"
print >>f, "</tr>"
print >>f, "</table>"
include(f, "footer.html")
finally:
f.close()
for point in POINTS:
chart("%s/%s.svg" % (BOOTCHARTS, point), CAPTIONS[point],
SSD_HOST, HDD_HOST,
all_dates,
times[SSD_HOST][point], times[HDD_HOST][point])
f = open("%s/index.html" % INSTALLER, "w")
try:
include(f, "header.html", {'title': "Daily installer testing" })
include(f, "installer.html")
print >>f, "<table>"
print >>f, "<tr>"
print >>f, "<th class=\"mast\"></th>"
print >>f, "<th class=\"mast\">max (SSD)</th>"
print >>f, "<th class=\"mast\">sam (HDD)</th></tr>"
for date in all_dates:
print >>f, "<tr>"
print >>f, "<th class=\"mast\">%s</th>" % date
if date in dates:
for host in (SSD_HOST, HDD_HOST):
path = "%s/%s-%s" % (INSTALLER, date, host)
if os.path.isfile("%s/WIN" % path):
print >>f, "<td class=\"win\">"
elif os.path.isfile("%s/FAIL" % path):
print >>f, "<td class=\"fail\">"
else:
print >>f, "<td></td>"
continue
print >>f, "<a href=\"%s-%s/bootchart.png\">bootchart</a>" % (date, host)
print >>f, "<a href=\"%s-%s/debug\">debug log</a>" % (date, host)
print >>f, "<a href=\"%s-%s/\">data</a>" % (date, host)
print >>f, "</td>"
else:
print >>f, "<td colspan=\"2\"></td>"
print >>f, "</tr>"
print >>f, "</table>"
include(f, "footer.html")
finally:
f.close()
def include(f, filename, dict={}):
h = open(filename)
try:
text = h.read()
print >>f, text % dict
finally:
h.close()
def chart(filename, caption, ssd_host, hdd_host, all_dates,
ssd_times, hdd_times):
width = max(10 + len(all_dates) * 2,
100)
height = max(31 + max(int(time * 5) for date, time in ssd_times),
31 + max(int(time * 5) for date, time in hdd_times),
100)
surface = cairo.SVGSurface(filename, width, height)
ctx = cairo.Context(surface)
ctx.set_line_width(1.0)
ctx.set_line_cap(cairo.LINE_CAP_SQUARE)
ctx.set_source_rgba(0.0, 0.0, 0.0, 1.0)
ctx.move_to(10, 9)
ctx.line_to(10, height-20)
ctx.line_to(width-1, height-20)
ctx.stroke()
for tick in range(20, height-9, 5):
y = height-tick
if tick%10:
ctx.move_to(7, y)
else:
ctx.move_to(5, y)
ctx.line_to(9, y)
ctx.stroke()
ctx.select_font_face("Bitstream Vera Sans")
ctx.set_font_size(8)
text_width = ctx.text_extents(caption)[2]
ctx.move_to((width-text_width)/2, 6)
ctx.show_text(caption)
ctx.move_to(6, 6)
ctx.show_text("seconds")
caption_xaxis = "First: %s, Last: %s" % (all_dates[0], all_dates[-1])
ctx.move_to((width - ctx.text_extents(caption_xaxis)[2])/2, height-12)
ctx.show_text( caption_xaxis )
ctx.set_line_cap(cairo.LINE_CAP_BUTT)
draw(ctx, all_dates, height, hdd_times, (0.0, 1.0, 0.0, 1.0))
draw(ctx, all_dates, height, ssd_times, (1.0, 0.0, 0.0, 1.0))
ctx.set_font_size(6)
ctx.set_line_width(0.5)
ctx.set_source_rgba(1.0, 0.0, 0.0, 1.0)
ctx.rectangle(10, height-16, 4, 4)
ctx.fill()
ctx.set_source_rgba(0.0, 0.0, 0.0, 1.0)
ctx.rectangle(10, height-16, 4, 4)
ctx.stroke()
ctx.move_to(17, height-12)
ctx.show_text("%s (SSD)" % SSD_HOST)
ctx.set_source_rgba(0.0, 1.0, 0.0, 1.0)
ctx.rectangle(10, height-10, 4, 4)
ctx.fill()
ctx.set_source_rgba(0.0, 0.0, 0.0, 1.0)
ctx.rectangle(10, height-10, 4, 4)
ctx.stroke()
ctx.move_to(17, height-6)
ctx.show_text("%s (HDD)" % HDD_HOST)
def draw(ctx, all_dates, height, times, color):
ctx.set_source_rgba(*color)
first = True
for date, time in sorted(times):
idx = len(all_dates)-all_dates.index(date)-1
x = 10 + 1 + idx * 2
y = height - 20 - 1 - time * 5
if first:
ctx.move_to(x,y)
first = False
else:
ctx.line_to(x,y)
ctx.stroke()
if __name__ == "__main__":
main(sys.argv[1:])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment