Commit 993d9fcd authored by Vincent Pelletier's avatar Vincent Pelletier

Replace matplotlib with js-based graphing.

parent 9fa71de0
......@@ -28,8 +28,6 @@
##############################################################################
# TODO:
# - use some templating system instead of hardcoded html strings
# - implement an alternative to matplotlib (inline SVG ? flotcharts ?) to have
# nice output with pypy
# - provide some form of raw data output, not just html
# - allow user to specify min & max dates
from cgi import escape
......@@ -40,20 +38,12 @@ from operator import itemgetter
from urllib import splittype, splithost
import argparse
import gzip
import json
import os
import re
import sys
import time
try:
import matplotlib
except ImportError:
matplotlib = None
else:
matplotlib.use('Agg')
import matplotlib.pyplot as pyplot
from matplotlib.dates import AutoDateLocator, AutoDateFormatter
MONTH_VALUE_DICT = dict((y, x) for (x, y) in enumerate(('Jan', 'Feb', 'Mar',
'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'), 1))
......@@ -384,6 +374,7 @@ period_parser = {
}
def main():
file_dir = os.path.dirname(__file__)
parser = argparse.ArgumentParser(description='Compute Apdex out of log files')
parser.add_argument('logfile', nargs='+',
help='Log files to process')
......@@ -418,6 +409,10 @@ def main():
help='Suppress warnings about malformed lines.')
parser.add_argument('-s', '--stats', action='store_true',
help='Enable parsing stats (time taken to parse all files, ...)')
parser.add_argument('--js', default=file_dir,
help='Folder containing needed js files. Default: %(default)s')
parser.add_argument('--js-embed', action='store_true',
help='Embed js files instead of linking to them.')
args = parser.parse_args()
line_regex = ''
try:
......@@ -524,56 +519,53 @@ def main():
'.stats th.text, .stats td.text { text-align: left; } '
'table.stats { border-collapse: collapse; } '
'.problem { background-color: #f00; color: white; } '
'.warning { background-color: #f80; color: white; }'
'</style></head><body><h1>Overall</h1>'
'.warning { background-color: #f80; color: white; } '
'h1 { background-color: #ccc; }'
'h2 { background-color: #eee; }'
'</style>')
for script in ('jquery.js', 'jquery.flot.js', 'jquery.flot.time.js',
'main.js'):
if args.js_embed:
out.write('<script type="text/javascript">//<![CDATA[')
out.write(getResource(script))
out.write('//]]></script>')
else:
out.write('<script type="text/javascript" src="%s/%s"></script>' % (
args.js, script))
out.write('</head><body><h1>Overall</h1>'
'<h2>Hits per day</h2><table class="stats"><tr><th>date</th><th>hits</th></tr>')
for date, hit in sorted(hit_per_day.iteritems(), key=ITEMGETTER0):
out.write('<tr><td>%s</td><td>%s</td></tr>' % (date, hit))
out.write('</table>')
def graph(title, data, options={}):
out.write('<h2>%s</h2><div class="graph" style="width:600px;height:300px" '
'data-points="' % title)
out.write(escape(json.dumps(data), quote=True))
out.write('" data-options="')
out.write(escape(json.dumps(options), quote=True))
out.write('"></div>')
for site_id, data in per_site.iteritems():
out.write('<h1>Site: %s</h1>' % site_id)
if matplotlib is not None:
daily_data = data.getApdexData()
date_list = [datetime.strptime(x[0], '%Y/%m/%d' + {'day': ' %H'}.get(
args.period, '')) for x in daily_data]
date_locator = AutoDateLocator(minticks=3, maxticks=5)
date_formatter = AutoDateFormatter(date_locator)
date_formatter.scaled = {
365.: '%Y',
30.: '%Y/%m',
1.: '%Y/%m/%d',
1. / 24: '%Y/%m/%d\n%H:%M',
}
apdex_plot = pyplot.subplot(2, 1, 1)
apdex_plot.xaxis.set_major_locator(date_locator)
apdex_plot.xaxis.set_major_formatter(date_formatter)
pyplot.title('Apdex')
pyplot.ylabel('%')
pyplot.plot(date_list, [x[1] for x in daily_data], '-')
pyplot.plot(date_list, [x[1] for x in daily_data], '.')
# response_time_plot = pyplot.subplot(3, 1, 2)
# response_time_plot.xaxis.set_major_locator(date_locator)
# response_time_plot.xaxis.set_major_formatter(date_formatter)
# pyplot.title('Response time')
# pyplot.ylabel('time (s)')
# pyplot.plot(date_list, [x[2] for x in daily_data], '-', label='Average')
# pyplot.plot(date_list, [x[3] for x in daily_data], '--', label='Max')
# pyplot.legend()
hit_plot = pyplot.subplot(2, 1, 2)
hit_plot.xaxis.set_major_locator(date_locator)
hit_plot.xaxis.set_major_formatter(date_formatter)
pyplot.title('Hits')
pyplot.plot(date_list, [x[4] for x in daily_data], '-')
pyplot.plot(date_list, [x[4] for x in daily_data], '.')
plot_filename = site_id.strip('/').replace('/', '__') + '.png'
pyplot.subplots_adjust(hspace=.4)
pyplot.savefig(plot_filename)
pyplot.clf()
out.write('<img src="' + plot_filename + '" />')
daily_data = data.getApdexData()
date_list = [int(time.mktime(time.strptime(x[0], '%Y/%m/%d' + {
'day': ' %H'}.get(args.period, ''))) * 1000) for x in daily_data]
graph('Apdex',
[zip(date_list, (x[1] for x in daily_data))],
{
'xaxis': {'mode': 'time'},
'yaxis': {'max': 100},
'lines': {'show': True},
'points': {'show': True},
},
)
graph('Hits',
[zip(date_list, (x[4] for x in daily_data))],
{
'xaxis': {'mode': 'time'},
'lines': {'show': True},
'points': {'show': True},
},
)
out.write(data.asHTML(decimator))
end_stat_time = time.time()
if args.stats:
......
$(function() {
$(".graph").each(function (i){
$.plot(
this,
$.parseJSON($(this).attr('data-points')),
$.parseJSON($(this).attr('data-options')));
});
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment