summaryrefslogtreecommitdiff
path: root/python/gras
diff options
context:
space:
mode:
Diffstat (limited to 'python/gras')
-rw-r--r--python/gras/CMakeLists.txt15
-rw-r--r--python/gras/stats/__init__.py36
-rw-r--r--python/gras/stats/main.html20
-rw-r--r--python/gras/stats/main.js88
4 files changed, 159 insertions, 0 deletions
diff --git a/python/gras/CMakeLists.txt b/python/gras/CMakeLists.txt
index ca38324..ad9bf9f 100644
--- a/python/gras/CMakeLists.txt
+++ b/python/gras/CMakeLists.txt
@@ -44,3 +44,18 @@ GR_PYTHON_INSTALL(
DESTINATION ${GR_PYTHON_DIR}/gras
COMPONENT ${GRAS_COMP_PYTHON}
)
+
+GR_PYTHON_INSTALL(
+ FILES
+ stats/__init__.py
+ DESTINATION ${GR_PYTHON_DIR}/gras/stats
+ COMPONENT ${GRAS_COMP_PYTHON}
+)
+
+INSTALL(
+ FILES
+ stats/main.html
+ stats/main.js
+ DESTINATION ${GR_PYTHON_DIR}/gras/stats
+ COMPONENT ${GRAS_COMP_PYTHON}
+)
diff --git a/python/gras/stats/__init__.py b/python/gras/stats/__init__.py
new file mode 100644
index 0000000..2ed52ea
--- /dev/null
+++ b/python/gras/stats/__init__.py
@@ -0,0 +1,36 @@
+import time
+import BaseHTTPServer
+
+import os
+__path__ = os.path.abspath(os.path.dirname(__file__))
+
+get_stats_registry = [lambda: ""]
+
+class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
+
+ def do_HEAD(s):
+ s.send_response(200)
+ s.send_header("Content-type", "text/html")
+ s.end_headers()
+
+ def do_GET(s):
+ """Respond to a GET request."""
+ if s.path.endswith('stats.xml'):
+ s.send_response(200)
+ s.send_header("Content-type", "text/xml")
+ s.end_headers()
+ s.wfile.write(get_stats_registry[0]())
+ return
+ s.send_response(200)
+ s.send_header("Content-type", "text/html")
+ s.end_headers()
+ path = s.path
+ if path.startswith('/'): path = path[1:]
+ if not path: path = 'main.html'
+ s.wfile.write(open(os.path.join(__path__, path)).read())
+
+def http_server(args, get_stats_xml):
+ get_stats_registry[0] = get_stats_xml
+ server_class = BaseHTTPServer.HTTPServer
+ httpd = server_class(args, MyHandler)
+ return httpd
diff --git a/python/gras/stats/main.html b/python/gras/stats/main.html
new file mode 100644
index 0000000..a58263a
--- /dev/null
+++ b/python/gras/stats/main.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
+ <title>GRAS status monitor</title>
+ <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
+ <script type="text/javascript" src="http://www.google.com/jsapi"></script>
+ <script type="text/javascript" src="/main.js"></script>
+ <script type="text/javascript">
+ google.load('visualization', '1.0', {'packages':['corechart']});
+ google.setOnLoadCallback(gras_stats_main);
+ </script>
+</head>
+
+<body>
+ <p id="tps">Default</p>
+ <div id="chart_div"></div>
+</body>
+
+</html>
diff --git a/python/gras/stats/main.js b/python/gras/stats/main.js
new file mode 100644
index 0000000..a29076b
--- /dev/null
+++ b/python/gras/stats/main.js
@@ -0,0 +1,88 @@
+/***********************************************************************
+ * Utility functions for stats
+ **********************************************************************/
+var gras_extract_block_ids = function(point)
+{
+ var ids = new Array();
+ $('block', point).each(function()
+ {
+ ids.push($(this).attr('id'));
+ });
+ return ids;
+}
+
+var gras_extract_throughput = function(point, id)
+{
+ var block_data = $('block[id="' + id + '"]', point);
+ var start_time = parseInt($('start_time', block_data).text());
+ var stats_time = parseInt($('stats_time', block_data).text());
+ var tps = parseInt($('tps', block_data).text());
+ var total_items = 0;
+ $('items_consumed,items_produced', block_data).each(function()
+ {
+ total_items += parseInt($(this).text());
+ });
+ return (total_items*tps)/(stats_time-start_time);
+}
+
+var gras_update_throughput_chart = function(history)
+{
+ var ids = gras_extract_block_ids(history[0]);
+ var data_set = [['Throughput'].concat(ids)];
+ for (var i = Math.max(history.length-10, 0); i < history.length; i++)
+ {
+ var row = new Array();
+ row.push(i.toString());
+ for (var j = 0; j < ids.length; j++)
+ {
+ row.push(gras_extract_throughput(history[i], ids[j])/1e6);
+ }
+ data_set.push(row);
+ }
+
+
+ var data = google.visualization.arrayToDataTable(data_set);
+
+ var options = {
+ title: 'Throughput per block over time',
+ vAxis: {title: "rate (MIps)"},
+ hAxis: {title: "time (seconds)"}
+ };
+
+ var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
+ chart.draw(data, options);
+
+}
+
+/***********************************************************************
+ * Query stats
+ **********************************************************************/
+var gras_query_stats = function(history)
+{
+ $.ajax({
+ type: "GET",
+ async: true,
+ url: "/stats.xml",
+ dataType: "xml",
+ success: function(xml)
+ {
+ if ($(xml, "gras_stats") !== undefined)
+ {
+ history.push(xml);
+ gras_update_throughput_chart(history);
+ }
+ var onceHandle = window.setTimeout(function() {
+ gras_query_stats(history);
+ }, 1000);
+ }
+ });
+}
+
+/***********************************************************************
+ * Init
+ **********************************************************************/
+var gras_stats_main = function()
+{
+ var history = new Array();
+ gras_query_stats(history);
+}