Commit e36ddfab authored by Vincent Pelletier's avatar Vincent Pelletier

Improve ERP5 table readability.

Vary line styles to make column & line groups easier to see.
Likewise for overall column group: separate clearly from periodic groups.
parent 6edcf4bf
...@@ -87,7 +87,7 @@ def getApdexStyle(apdex): ...@@ -87,7 +87,7 @@ def getApdexStyle(apdex):
('%x' % (apdex * 0xf)) * 3, ('%x' % (apdex * 0xf)) * 3,
) )
def getApdexStatsAsHtml(data, threshold): def getApdexStatsAsHtml(data, threshold, overall=False):
apdex = data.getApdex() apdex = data.getApdex()
average = data.getAverage() average = data.getAverage()
maximum = data.getMax() maximum = data.getMax()
...@@ -98,10 +98,15 @@ def getApdexStatsAsHtml(data, threshold): ...@@ -98,10 +98,15 @@ def getApdexStatsAsHtml(data, threshold):
else: else:
extra_class = 'no_hit' extra_class = 'no_hit'
apdex_style = '' apdex_style = ''
return '<td style="%(apdex_style)s" class="%(extra_class)s">%(apdex)i%%' \ if overall:
'</td><td class="%(extra_class)s">%(hit)s</td>' \ extra_right_class = 'overall_right'
else:
extra_right_class = ''
return '<td style="%(apdex_style)s" class="%(extra_class)s group_left">' \
'%(apdex)i%%</td><td class="%(extra_class)s">%(hit)s</td>' \
'<td class="%(average_class)s %(extra_class)s">%(average).2f</td>' \ '<td class="%(average_class)s %(extra_class)s">%(average).2f</td>' \
'<td class="%(max_class)s %(extra_class)s">%(max).2f</td>' % { '<td class="%(max_class)s %(extra_class)s group_right ' \
'%(extra_right_class)s">%(max).2f</td>' % {
'extra_class': extra_class, 'extra_class': extra_class,
'apdex_style': apdex_style, 'apdex_style': apdex_style,
'apdex': apdex * 100, 'apdex': apdex * 100,
...@@ -110,10 +115,16 @@ def getApdexStatsAsHtml(data, threshold): ...@@ -110,10 +115,16 @@ def getApdexStatsAsHtml(data, threshold):
'average': average, 'average': average,
'max_class': getClassForDuration(maximum, threshold), 'max_class': getClassForDuration(maximum, threshold),
'max': maximum, 'max': maximum,
'extra_right_class': extra_right_class,
} }
APDEX_TABLE_HEADERS = ''.join('<th>' + x + '</th>' for x in ( def getApdexTableHeader(overall=False):
'apdex', 'hits', 'avg (s)', 'max (s)')) if overall:
extra = ' class="overall_right"'
else:
extra = ''
return '<th>apdex</th><th>hits</th><th>avg (s)</th>' \
'<th%s>max (s)</th>' % extra
class APDEXStats(object): class APDEXStats(object):
def __init__(self, threshold, getDuration): def __init__(self, threshold, getDuration):
...@@ -199,11 +210,11 @@ class GenericSiteStats(object): ...@@ -199,11 +210,11 @@ class GenericSiteStats(object):
for data in self.apdex.itervalues(): for data in self.apdex.itervalues():
apdex.accumulateFrom(data) apdex.accumulateFrom(data)
append('<h2>Overall</h2><table class="stats"><tr>') append('<h2>Overall</h2><table class="stats"><tr>')
append(APDEX_TABLE_HEADERS) append(getApdexTableHeader())
append('</tr><tr>') append('</tr><tr>')
append(getApdexStatsAsHtml(apdex, self.threshold)) append(getApdexStatsAsHtml(apdex, self.threshold))
append('</tr></table><h2>Hottest pages</h2><table class="stats"><tr>') append('</tr></table><h2>Hottest pages</h2><table class="stats"><tr>')
append(APDEX_TABLE_HEADERS) append(getApdexTableHeader())
append('<th>url</th></tr>') append('<th>url</th></tr>')
for url, data in sorted(self.url_apdex.iteritems(), key=lambda x: x[1].getAverage() * x[1].hit, for url, data in sorted(self.url_apdex.iteritems(), key=lambda x: x[1].getAverage() * x[1].hit,
reverse=True)[:N_SLOWEST]: reverse=True)[:N_SLOWEST]:
...@@ -303,8 +314,9 @@ class ERP5SiteStats(GenericSiteStats): ...@@ -303,8 +314,9 @@ class ERP5SiteStats(GenericSiteStats):
def asHTML(self, stat_filter=lambda x: x): def asHTML(self, stat_filter=lambda x: x):
result = [] result = []
append = result.append append = result.append
append('<h2>Stats per module</h2><table class="stats"><tr>' append('<h2>Stats per module</h2><table class="stats stats_erp5"><tr>'
'<th rowspan="2" colspan="2">module</th><th colspan="4">overall</th>') '<th rowspan="2" colspan="2">module</th>'
'<th colspan="4" class="overall_right">overall</th>')
filtered_module = defaultdict(partial(defaultdict, partial( filtered_module = defaultdict(partial(defaultdict, partial(
defaultdict, partial(APDEXStats, self.threshold, None)))) defaultdict, partial(APDEXStats, self.threshold, None))))
filtered_no_module = defaultdict(partial(APDEXStats, self.threshold, None)) filtered_no_module = defaultdict(partial(APDEXStats, self.threshold, None))
...@@ -322,24 +334,25 @@ class ERP5SiteStats(GenericSiteStats): ...@@ -322,24 +334,25 @@ class ERP5SiteStats(GenericSiteStats):
for date in column_list: for date in column_list:
append('<th colspan="4">%s</th>' % date) append('<th colspan="4">%s</th>' % date)
append('</tr><tr>') append('</tr><tr>')
for _ in xrange(len(column_list) + 1): for i in xrange(len(column_list) + 1):
append(APDEX_TABLE_HEADERS) append(getApdexTableHeader(i == 0))
append('</tr>') append('</tr>')
def apdexAsColumns(data_dict): def apdexAsColumns(data_dict):
data_total = APDEXStats(self.threshold, None) data_total = APDEXStats(self.threshold, None)
for data in data_dict.values(): for data in data_dict.values():
data_total.accumulateFrom(data) data_total.accumulateFrom(data)
append(getApdexStatsAsHtml(data_total, self.threshold)) append(getApdexStatsAsHtml(data_total, self.threshold, True))
for date in column_list: for date in column_list:
append(getApdexStatsAsHtml(data_dict[date], self.threshold)) append(getApdexStatsAsHtml(data_dict[date], self.threshold))
for module_id, data_dict in sorted(filtered_module.iteritems(), for module_id, data_dict in sorted(filtered_module.iteritems(),
key=ITEMGETTER0): key=ITEMGETTER0):
append('<tr><th rowspan="2">%s</th><th>module</th>' % module_id) append('<tr class="group_top"><th rowspan="2">%s</th>'
'<th>module</th>' % module_id)
apdexAsColumns(data_dict[False]) apdexAsColumns(data_dict[False])
append('</tr><tr><th>document</th>') append('</tr><tr class="group_bottom"><th>document</th>')
apdexAsColumns(data_dict[True]) apdexAsColumns(data_dict[True])
append('</tr>') append('</tr>')
append('<tr><th colspan="2">(none)</th>') append('<tr class="group_top group_bottom"><th colspan="2">(none)</th>')
apdexAsColumns(filtered_no_module) apdexAsColumns(filtered_no_module)
append('</tr></table>') append('</tr></table>')
append(super(ERP5SiteStats, self).asHTML(stat_filter=stat_filter)) append(super(ERP5SiteStats, self).asHTML(stat_filter=stat_filter))
...@@ -616,6 +629,12 @@ def main(): ...@@ -616,6 +629,12 @@ def main():
'.stats td { text-align: right; } ' '.stats td { text-align: right; } '
'.stats th.text, .stats td.text { text-align: left; } ' '.stats th.text, .stats td.text { text-align: left; } '
'.stats td.no_hit { color: #ccc; } ' '.stats td.no_hit { color: #ccc; } '
'.stats_erp5 td { border-style: dotted; } '
'.stats_erp5 tr.group_top td { border-top-style: solid; } '
'.stats_erp5 tr.group_bottom td { border-bottom-style: solid; } '
'.stats_erp5 td.group_left { border-left-style: solid; } '
'.stats_erp5 td.group_right { border-right-style: solid; } '
'.stats_erp5 .overall_right { border-right-width: .2em; } '
'table.stats { border-collapse: collapse; } ' 'table.stats { border-collapse: collapse; } '
'.problem { background-color: #f00; color: white; } ' '.problem { background-color: #f00; color: white; } '
'.warning { background-color: #f80; color: white; } ' '.warning { background-color: #f80; color: white; } '
......
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