Display:
"""
lev = tldata.level_order(data)
for num, name in enumerate(lev):
graph += T("""\
""").substitute({"id": num, "name": name})
graph += """
Drag to zoom. Double click to zoom out again
"""
for j in lev:
graph += T("""
"""
return graph
def gen_html_cpu(cpu):
lev = tldata.level_order(data)
graph = ""
for name in lev:
opts = {
"title": name + " " + cpu,
"width": 1000,
"height": 180,
#"xlabel": "time",
}
if name in data.metrics:
unit = gen_level.get_unit(list(data.levels[name])[0])
if unit:
opts["ylabel"] = unit
else:
opts["stackedGraph"] = 1
opts["stackedGraphNaNFill"] = "none"
opts["ylabel"] = "% CPU time"
unit = '%'
if unit == '%':
opts["valueRange"] = [-5, 110]
graph += T("""
""").substitute({"name": name, "jname": jsname(name), "file": name, "cpu": cpu, "opts": opts})
return graph
def gen_html():
graph = gen_html_header()
for cpu in sorted(data.cpus):
graph += gen_html_cpu(cpu)
graph += """
"""
return graph
def get_postfix(s):
m = re.match(r'.*\.(.*)', s)
if m:
return m.group(1)
return s
def gencsv(wfile, l, cpu):
hdr = sorted(data.levels[l])
wr = csv.writer(wfile)
wr.writerow(["Timestamp"] + map(get_postfix, hdr))
for val, ts in zip(data.vals, data.times):
wr.writerow([ts] + [val[(x, cpu)] if (x, cpu) in val else "" for x in hdr])
class TLHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def header(self, type):
self.send_response(200)
self.send_header('Content-Type', type)
self.end_headers()
def bad(self):
self.send_response(401)
self.send_header('Content-Type', 'text/html')
self.end_headers()
self.wfile.write("%s not found" % (self.path))
def serve_file(self, fn, mime):
with open(fn, "r") as f:
self.header(mime)
self.wfile.write(f.read())
def do_GET(self):
if self.path == "/":
self.header("text/html")
self.wfile.write(gen_html())
elif self.path == "/dygraph-combined.js":
self.serve_file("dygraph-combined.js", "text/javascript")
elif self.path == "/toplev.ico":
self.serve_file("toplev.ico", "image/x-icon")
elif self.path.endswith(".csv"):
data.update()
m = re.match(r"/(cpu|C\d+|S\d+-C\d+|C\d+-T\d+)\.(.*?)\.csv", self.path)
if not m:
self.bad()
return
cpu = m.group(1)
l = m.group(2)
if l not in data.levels:
self.bad()
return
self.header("text/csv")
gencsv(self.wfile, l, cpu)
else:
self.bad()
def copyfile(a, b):
with open(a, "r") as af:
with open(b, "w") as bf:
bf.write(af.read())
if args.gen:
if not os.path.isdir(args.gen):
os.makedirs(args.gen)
genfn = os.path.join
with open(genfn(args.gen, "index.html"), 'w') as f:
f.write(gen_html())
copyfile('dygraph-combined.js', genfn(args.gen, 'dygraph-combined.js'))
copyfile('toplev.ico', genfn(args.gen, 'favicon.ico'))
for cpu in data.cpus:
for l in data.levels:
with open(genfn(args.gen, cpu + "." + l + ".csv"), 'w') as f:
gencsv(f, l, cpu)
print "Please browse", args.gen, "through a web server, not through file:"
else:
httpd = BaseHTTPServer.HTTPServer((args.host, args.port), TLHandler)
print "serving at",args.host,"port",args.port,"until Ctrl-C"
try:
httpd.serve_forever()
except KeyboardInterrupt:
httpd.socket.close()