Do not pipe into `grep -q`, because that stops reading as soon as a
[arvados.git] / tools / crunchstat-summary / crunchstat_summary / webchart.py
1 # Copyright (C) The Arvados Authors. All rights reserved.
2 #
3 # SPDX-License-Identifier: AGPL-3.0
4
5 try:
6     from html import escape
7 except ImportError:
8     from cgi import escape
9
10 import json
11 import pkg_resources
12
13
14 class WebChart(object):
15     """Base class for a web chart.
16
17     Subclasses must assign JSLIB and JSASSETS, and override the
18     chartdata() method.
19     """
20     JSLIB = None
21     JSASSET = None
22
23     def __init__(self, label, summarizers):
24         self.label = label
25         self.summarizers = summarizers
26
27     def html(self):
28         return '''<!doctype html><html><head>
29         <title>{} stats</title>
30         <script type="text/javascript" src="{}"></script>
31         <script type="text/javascript">{}</script>
32         {}
33         </head><body></body></html>
34         '''.format(escape(self.label),
35                    self.JSLIB, self.js(), self.headHTML())
36
37     def js(self):
38         return 'var chartdata = {};\n{}'.format(
39             json.dumps(self.sections()),
40             '\n'.join([pkg_resources.resource_string('crunchstat_summary', jsa).decode('utf-8') for jsa in self.JSASSETS]))
41
42     def sections(self):
43         return [
44             {
45                 'label': s.long_label(),
46                 'charts': [
47                     self.chartdata(s.label, s.tasks, stat)
48                     for stat in (('cpu', ['user+sys__rate', 'user__rate', 'sys__rate']),
49                                  ('mem', ['rss']),
50                                  ('net:eth0', ['tx+rx__rate','rx__rate','tx__rate']),
51                                  ('net:keep0', ['tx+rx__rate','rx__rate','tx__rate']),
52                                  ('statfs', ['used', 'total']),
53                                  )
54                     ],
55             }
56             for s in self.summarizers]
57
58     def chartdata(self, label, tasks, stat):
59         """Return chart data for the given tasks.
60
61         The returned value will be available on the client side as an
62         element of the "chartdata" array.
63         """
64         raise NotImplementedError()
65
66     def headHTML(self):
67         """Return extra HTML text to include in HEAD."""
68         return ''