1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: AGPL-3.0
6 from html import escape
11 from typing import ItemsView
15 class WebChart(object):
16 """Base class for a web chart.
18 Subclasses must assign JSLIB and JSASSETS, and override the
27 font-family: "Roboto", "Helvetica", "Arial", sans-serif;
29 color: rgba(0, 0, 0, 0.87);
34 box-shadow: 0px 1px 5px 0px rgba(0,0,0,0.2),0px 2px 2px 0px rgba(0,0,0,0.14),0px 3px 1px -2px rgba(0,0,0,0.12);
39 padding: 2px 16px 8px 16px;
50 border-top: 1px solid rgba(224, 224, 224, 1);
54 border-top: 1px solid rgba(224, 224, 224, 1);
61 def __init__(self, label, summarizers):
63 self.summarizers = summarizers
65 def cardlist(self, items):
66 if not isinstance(items, list):
74 </div>""".format(i) for i in items)
76 def html(self, beforechart='', afterchart=''):
84 <div id="chart"></div>
89 return '''<!doctype html><html><head>
90 <title>{label} stats</title>
91 <script type="text/javascript" src="{jslib}"></script>
92 <script type="text/javascript">{ourjs}</script>
100 <div class="content">
109 '''.format(label=escape(self.label),
113 header=self.headHTML(),
114 beforegraph=self.cardlist(beforechart),
116 aftergraph=self.cardlist(afterchart))
119 return 'var chartdata = {};\n{}'.format(
120 json.dumps(self.sections()),
121 '\n'.join([pkg_resources.resource_string('crunchstat_summary', jsa).decode('utf-8') for jsa in self.JSASSETS]))
126 'label': s.long_label(),
128 self.chartdata(s.label, s.tasks, stat)
129 for stat in (('cpu', ['user+sys__rate', 'user__rate', 'sys__rate']),
131 ('net:eth0', ['tx+rx__rate','rx__rate','tx__rate']),
132 ('net:keep0', ['tx+rx__rate','rx__rate','tx__rate']),
133 ('statfs', ['used', 'total']),
137 for s in self.summarizers]
139 def chartdata(self, label, tasks, stat):
140 """Return chart data for the given tasks.
142 The returned value will be available on the client side as an
143 element of the "chartdata" array.
145 raise NotImplementedError()
148 """Return extra HTML text to include in HEAD."""