--- /dev/null
+{% extends "base.html" %}
+
+{% block content %}
+
+<script>
+ $(document).ready(function(){
+ // Pre-populated initial data at page load
+ var content_data = {{ content_data }};
+
+ var hexdigits = function(v) {
+ var i = Math.floor(v * 255);
+ if (Math.floor(i) < 0x10) {
+ return "0" + Math.floor(i).toString(16);
+ } else {
+ return Math.floor(i).toString(16);
+ }
+ };
+
+ var hexcolor = function(r, g, b) {
+ return "#" + hexdigits(r) + hexdigits(g) + hexdigits(b);
+ };
+
+ var last = {};
+
+ var render = function(element, counter) {
+ var data = content_data.osd_histogram.osd[counter];
+ var hist_table = $(element);
+ hist_table.empty();
+
+ var sum = 0.0;
+ var max = 0.0;
+ $.each(data.values, function(i, row) {
+ $.each(row, function(j, col) {
+ var val;
+ if (!last[counter]) {
+ val = col;
+ } else {
+ val = col - last[counter][i][j];
+ }
+ sum += val;
+ max = Math.max(max, val);
+ });
+ });
+
+
+ $.each(data.values, function(i, row) {
+ var tr = $("<tr style='height: 10px;'></tr>").appendTo(hist_table);
+ $.each(row, function(j, col) {
+ var td = $("<td style='width: 10px; height: 10px;'></td>").appendTo(tr);
+ var val;
+ if (!last[counter]) {
+ val = col;
+ } else {
+ val = col - last[counter][i][j];
+ }
+
+
+ var g;
+ if (max) {
+ g = (val / max);
+ } else {
+ g = 0.0;
+ }
+ var r = 1.0 - g;
+ var b = 0.0;
+
+ td.css("background-color", hexcolor(r, g, b));
+ });
+ });
+
+ last[counter] = data.values;
+ };
+
+ var post_load = function() {
+ content_data.osd_metadata_list = [];
+ content_data.osd_list = [];
+ _.each(content_data.osd_metadata, function(v, k) {
+ content_data.osd_metadata_list.push({
+ key: k,
+ value: v
+ });
+ });
+ _.each(content_data.osd, function(v, k) {
+ content_data.osd_list.push({
+ key: k,
+ value: v
+ });
+ });
+ render("#heatmap_write",
+ "op_w_latency_in_bytes_histogram");
+ render("#heatmap_read",
+ "op_r_latency_out_bytes_histogram");
+ };
+
+ rivets.bind($("div#content"), content_data);
+ post_load();
+
+ var refresh = function() {
+ $.get("{{ url_prefix }}/osd/perf_data/" + content_data.osd.osd + "/", function(data) {
+ _.extend(content_data.osd_histogram, data.osd_histogram);
+ _.extend(content_data.osd, data.osd);
+ _.extend(content_data.osd_metadata, data.osd_metadata);
+
+ post_load();
+ setTimeout(refresh, 3000);
+ });
+ };
+
+ // Wait 1s to load irrespective of normal frequency,
+ // to promptly load our first delta
+ setTimeout(refresh, 1000);
+ });
+</script>
+
+
+<section class="content-header">
+ <h1>
+ osd.{osd.osd}
+ </h1>
+</section>
+
+<section class="content">
+
+ <table>
+ <tr>
+ <td>
+ <h3>Writes</h3>
+ <table id="heatmap_write">
+ </table>
+ </td><td> </td><td>
+ <h3>Reads</h3>
+ <table id="heatmap_read">
+ </table>
+ </td>
+ </tr>
+ </table>
+
+<div class="box">
+ <div class="box-header">
+ <h3 class="box-title">Attributes (OSD map)</h3>
+ </div>
+ <div class="box-body">
+ <table>
+ <thead>
+ <tr>
+ <th>Key</th>
+ <th>Value</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr rv-each-item="osd_list">
+ <td>{item.key}</td>
+ <td>{item.value}</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+</div>
+
+<div class="box">
+ <div class="box-header">
+ <h3 class="box-title">Metadata</h3>
+ </div>
+ <div class="box-body">
+ <table>
+ <thead>
+ <tr>
+ <th>Key</th>
+ <th>Value</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr rv-each-meta_item="osd_metadata_list">
+ <td>{meta_item.key}</td>
+ <td>{meta_item.value}</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+</div>
+
+
+</section>
+<!-- /.content -->
+
+{% endblock %}