8784: Fix test for latest firefox.
[arvados.git] / tools / crunchstat-summary / crunchstat_summary / chartjs.py
1 from __future__ import print_function
2
3 import cgi
4 import json
5 import math
6 import pkg_resources
7
8 from crunchstat_summary import logger
9
10
11 class ChartJS(object):
12     JSLIB = 'https://cdnjs.cloudflare.com/ajax/libs/canvasjs/1.7.0/canvasjs.min.js'
13
14     def __init__(self, label, summarizers):
15         self.label = label
16         self.summarizers = summarizers
17
18     def html(self):
19         return '''<!doctype html><html><head>
20         <title>{} stats</title>
21         <script type="text/javascript" src="{}"></script>
22         <script type="text/javascript">{}</script>
23         </head><body></body></html>
24         '''.format(cgi.escape(self.label), self.JSLIB, self.js())
25
26     def js(self):
27         return 'var sections = {};\n{}'.format(
28             json.dumps(self.sections()),
29             pkg_resources.resource_string('crunchstat_summary', 'chartjs.js'))
30
31     def sections(self):
32         return [
33             {
34                 'label': s.long_label(),
35                 'charts': self.charts(s.label, s.tasks),
36             }
37             for s in self.summarizers]
38
39     def _axisY(self, tasks, stat):
40         ymax = 1
41         for task in tasks.itervalues():
42             for pt in task.series[stat]:
43                 ymax = max(ymax, pt[1])
44         ytick = math.exp((1+math.floor(math.log(ymax, 2)))*math.log(2))/4
45         return {
46             'gridColor': '#cccccc',
47             'gridThickness': 1,
48             'interval': ytick,
49             'minimum': 0,
50             'maximum': ymax,
51             'valueFormatString': "''",
52         }
53
54     def charts(self, label, tasks):
55         return [
56             {
57                 'axisY': self._axisY(tasks=tasks, stat=stat),
58                 'data': [
59                     {
60                         'type': 'line',
61                         'markerType': 'none',
62                         'dataPoints': self._datapoints(
63                             label=uuid, task=task, series=task.series[stat]),
64                     }
65                     for uuid, task in tasks.iteritems()
66                 ],
67                 'title': {
68                     'text': '{}: {} {}'.format(label, stat[0], stat[1]),
69                 },
70                 'zoomEnabled': True,
71             }
72             for stat in (('cpu', 'user+sys__rate'),
73                          ('mem', 'rss'),
74                          ('net:eth0', 'tx+rx__rate'),
75                          ('net:keep0', 'tx+rx__rate'))]
76
77     def _datapoints(self, label, task, series):
78         points = [
79             {'x': pt[0].total_seconds(), 'y': pt[1]}
80             for pt in series]
81         if len(points) > 0:
82             points[-1]['markerType'] = 'cross'
83             points[-1]['markerSize'] = 12
84         return points