Matthias keeps asking "where are the pretty charts?" So here they are.
This commit is contained in:
parent
e8841ba530
commit
9051356e7a
|
|
@ -39,8 +39,10 @@ div.box, div.section, div.section-hidden { overflow: auto; width: 100%; }
|
|||
.right { float: right; }
|
||||
.clear { clear: both; }
|
||||
|
||||
.help { color: #888; cursor: pointer; }
|
||||
.help:hover { color: #444; }
|
||||
.help, .rate-options { color: #888; cursor: pointer; }
|
||||
.help:hover, .rate-options:hover { color: #444; }
|
||||
|
||||
.rate-options-p { padding-top: 10px; clear: both; }
|
||||
|
||||
table { border-collapse: collapse; }
|
||||
table th { font-weight: normal; color: black; }
|
||||
|
|
@ -56,10 +58,6 @@ table.list th a.sort .arrow { color: #888; }
|
|||
table.list td p { margin: 0; padding: 1px 0 0 0; }
|
||||
table.list td p.warning { margin: 0; padding: 5px; }
|
||||
|
||||
table.list-with-total { border-bottom: none; }
|
||||
table.list tr.total td { border: none; border-top: 1px solid #bbb; }
|
||||
table.list tr.total th { border: none; border-top: 1px solid #bbb; text-align: right; vertical-align: middle; }
|
||||
|
||||
div.section table.list, div.section-hidden table.list { margin-bottom: 0; }
|
||||
|
||||
div.memory-bar { margin: 10px 0 5px 0; border-radius: 5px; border: 1px solid #ddd; float: left; }
|
||||
|
|
@ -122,7 +120,7 @@ p.status-error th { background: white; }
|
|||
p.warning, div.form-popup-warn { background: #ff8; border: 1px solid #bb8; }
|
||||
div.form-popup-info { background: #8f8; border: 1px solid #4b4; }
|
||||
div.form-popup-help { text-align: left !important; background: #f8f8f8; border: 1px solid #ccc; }
|
||||
div.form-popup-warn, div.form-popup-info, div.form-popup-help { margin: 20px; padding: 15px; border-radius: 10px; -moz-border-radius: 10px; text-align: center; max-width: 600px; }
|
||||
div.form-popup-warn, div.form-popup-info, div.form-popup-help { margin: 20px; padding: 15px; border-radius: 10px; -moz-border-radius: 10px; text-align: center; max-width: 600px; z-index: 1; }
|
||||
|
||||
p.status-error, p.warning { margin: 20px; padding: 15px; border-radius: 10px; -moz-border-radius: 10px; text-align: center; font-weight: bold; }
|
||||
|
||||
|
|
@ -130,6 +128,11 @@ p.status-error, p.warning { margin: 20px; padding: 15px; border-radius: 10px; -m
|
|||
.highlight strong { font-size: 2em; display: block; color: #444; font-weight: normal; }
|
||||
.highlight, .micro-highlight { float: left; }
|
||||
|
||||
.chart { margin: 20px 0; }
|
||||
.chart-small { width: 600px; height: 200px; }
|
||||
.chart-medium { width: 800px; height: 300px; }
|
||||
.chart-large { width: 1200px; height: 400px; }
|
||||
|
||||
.mini-highlight { font-size: 150%; padding:10px; background-color: #ddd; color: #888; border-radius: 10px; -moz-border-radius: 10px; line-height: 300%; }
|
||||
|
||||
.micro-highlight { min-width: 120px; font-size: 100%; text-align:center; padding:10px; background-color: #ddd; margin: 0 20px 0 0; color: #888; border-radius: 10px; -moz-border-radius: 10px; }
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
<title>RabbitMQ Management</title>
|
||||
<script src="js/ejs.js" type="text/javascript"></script>
|
||||
<script src="js/jquery-1.6.4.min.js" type="text/javascript"></script>
|
||||
<script src="js/jquery.flot.min.js" type="text/javascript"></script>
|
||||
<script src="js/sammy-0.6.0.min.js" type="text/javascript"></script>
|
||||
<script src="js/json2.js" type="text/javascript"></script>
|
||||
<script src="js/base64.js" type="text/javascript"></script>
|
||||
|
|
@ -11,11 +12,13 @@
|
|||
<script src="js/prefs.js" type="text/javascript"></script>
|
||||
<script src="js/help.js" type="text/javascript"></script>
|
||||
<script src="js/formatters.js" type="text/javascript"></script>
|
||||
<script src="js/charts.js" type="text/javascript"></script>
|
||||
|
||||
<link href="css/main.css" rel="stylesheet" type="text/css"/>
|
||||
<link href="favicon.ico" rel="shortcut icon" type="image/x-icon"/>
|
||||
|
||||
<!--[if lte IE 8]>
|
||||
<script src="js/excanvas.min.js" type="text/javascript"></script>
|
||||
<link href="css/evil.css" rel="stylesheet" type="text/css"/>
|
||||
<![endif]-->
|
||||
</head>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
function render_charts() {
|
||||
$('.chart').map(function() {
|
||||
render_chart($(this));
|
||||
});
|
||||
}
|
||||
|
||||
function render_chart(div) {
|
||||
var chrome = {
|
||||
series: { lines: { show: true } },
|
||||
grid: { borderWidth: 2, borderColor: "#aaa" },
|
||||
xaxis: { tickColor: "#fff", mode: "time" },
|
||||
yaxis: { tickColor: "#eee", min: 0 },
|
||||
legend: { position: 'se', backgroundOpacity: 0.5 }
|
||||
};
|
||||
|
||||
var data = [];
|
||||
for (var name in chart_data) {
|
||||
var samples = chart_data[name].samples;
|
||||
var d = [];
|
||||
for (var i = 1; i < samples.length; i++) {
|
||||
var x = samples[i].timestamp;
|
||||
var y = (samples[i - 1].sample - samples[i].sample) * 1000 /
|
||||
(samples[i - 1].timestamp - samples[i].timestamp);
|
||||
d.push([x, y]);
|
||||
}
|
||||
data.push({label: name + " (" + chart_data[name].rate + " msg/s)",
|
||||
data: d});
|
||||
}
|
||||
chart_data = {};
|
||||
|
||||
$.plot(div, data, chrome);
|
||||
}
|
||||
|
||||
function update_rate_options(sammy) {
|
||||
store_pref('rate-mode', sammy.params['mode']);
|
||||
store_pref('chart-size', sammy.params['size']);
|
||||
partial_update();
|
||||
}
|
||||
|
|
@ -178,4 +178,7 @@ dispatcher_add(function(sammy) {
|
|||
sammy.get('#/import-succeeded', function() {
|
||||
render({}, 'import-succeeded', '#/overview');
|
||||
});
|
||||
sammy.put('#/rate-options', function() {
|
||||
update_rate_options(this);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -536,8 +536,9 @@ function _link_to(name, url) {
|
|||
return '<a href="' + url + '">' + name + '</a>';
|
||||
}
|
||||
|
||||
function message_rates(stats) {
|
||||
var res = "";
|
||||
function message_rates(stats, map) {
|
||||
var res = '';
|
||||
|
||||
if (keys(stats).length > 0) {
|
||||
var items = [['Publish', 'publish'], ['Confirm', 'confirm'],
|
||||
['Deliver', 'deliver'],
|
||||
|
|
@ -548,14 +549,18 @@ function message_rates(stats) {
|
|||
['Return', 'return_unroutable']];
|
||||
for (var i in items) {
|
||||
var name = items[i][0];
|
||||
var key = items[i][1] + '_details';
|
||||
if (key in stats) {
|
||||
res += '<div class="highlight">' + name;
|
||||
res += '<strong>' + fmt_rate_num(stats[key].rate) + '</strong>';
|
||||
res += 'msg/s</div>';
|
||||
if (map != undefined && name in map) {
|
||||
items[i][0] = map[name];
|
||||
}
|
||||
}
|
||||
|
||||
var res;
|
||||
var mode = get_pref('rate-mode');
|
||||
if (mode == 'chart') {
|
||||
res = message_rates_chart(items, stats);
|
||||
}
|
||||
else {
|
||||
res = message_rates_text(items, stats, mode);
|
||||
}
|
||||
if (res == "") {
|
||||
res = '<p>Waiting for message rates...</p>';
|
||||
}
|
||||
|
|
@ -564,6 +569,36 @@ function message_rates(stats) {
|
|||
res = '<p>Currently idle</p>';
|
||||
}
|
||||
|
||||
return res + '<p class="rate-options-p"><span class="rate-options">[Options...]</span></p>';
|
||||
}
|
||||
|
||||
function message_rates_chart(items, stats) {
|
||||
var size = get_pref('chart-size');
|
||||
var show = false;
|
||||
for (var i in items) {
|
||||
var name = items[i][0];
|
||||
var key = items[i][1] + '_details';
|
||||
if (key in stats) {
|
||||
chart_data[name] = stats[key];
|
||||
show = true;
|
||||
}
|
||||
}
|
||||
return show ? '<div class="chart chart-' + size + '"></div>' : '';
|
||||
}
|
||||
|
||||
function message_rates_text(items, stats, mode) {
|
||||
var res = '';
|
||||
for (var i in items) {
|
||||
var name = items[i][0];
|
||||
var key = items[i][1] + '_details';
|
||||
if (key in stats) {
|
||||
var num = mode == 'avg' ? stats[key].avg_rate : stats[key].rate;
|
||||
res += '<div class="highlight">' + name;
|
||||
res += '<strong>' + fmt_rate_num(num) + '</strong>';
|
||||
res += 'msg/s';
|
||||
res += '</div>';
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -614,6 +649,12 @@ function fmt_permissions(obj, permissions, lookup, show, warning) {
|
|||
return res.length == 0 ? warning : res.join(', ');
|
||||
}
|
||||
|
||||
function fmt_option(name, value, current) {
|
||||
return '<option value="' + value + '"' +
|
||||
((value == current) ? ' selected="selected"' : '') +
|
||||
'>' + name + '</option>';
|
||||
}
|
||||
|
||||
function properties_size(obj) {
|
||||
var count = 0;
|
||||
for (k in obj) {
|
||||
|
|
|
|||
|
|
@ -127,3 +127,6 @@ var last_successful_connect;
|
|||
// TODO: maybe we don't need this any more?
|
||||
var update_counter = 0;
|
||||
|
||||
// Used to hold chart data in between writing the div in an ejs and
|
||||
// rendering the chart.
|
||||
var chart_data = {};
|
||||
|
|
|
|||
|
|
@ -194,6 +194,7 @@ function update() {
|
|||
replace_content('main', html);
|
||||
postprocess();
|
||||
postprocess_partial();
|
||||
render_charts();
|
||||
maybe_scroll();
|
||||
reset_timer();
|
||||
});
|
||||
|
|
@ -219,6 +220,7 @@ function partial_update() {
|
|||
}
|
||||
replace_content('scratch', '');
|
||||
postprocess_partial();
|
||||
render_charts();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -432,9 +434,15 @@ function postprocess() {
|
|||
$('.help').die().live('click', function() {
|
||||
help($(this).attr('id'))
|
||||
});
|
||||
$('.rate-options').die().live('click', function() {
|
||||
show_popup('help', format('rate-options', {}));
|
||||
});
|
||||
$('input, select').live('focus', function() {
|
||||
update_counter = 0; // If there's interaction, reset the counter.
|
||||
});
|
||||
$('form.auto-submit select, form.auto-submit input').live('click', function(){
|
||||
$(this).parents('form').submit();
|
||||
});
|
||||
if (! user_administrator) {
|
||||
$('.administrator-only').remove();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,16 @@
|
|||
<h1>Channel: <b><%= fmt_escape_html(channel.name) %></b></h1>
|
||||
|
||||
<div class="section">
|
||||
<h2>Details</h2>
|
||||
<h2>Overview</h2>
|
||||
<div class="hider updatable">
|
||||
<% if (statistics_level == 'fine') { %>
|
||||
<h3>Message rates</h3>
|
||||
<div class="box">
|
||||
<%= message_rates(channel.message_stats) %>
|
||||
</div>
|
||||
<% } %>
|
||||
|
||||
<h3>Details</h3>
|
||||
<table class="facts">
|
||||
<tr>
|
||||
<th>Connection</th>
|
||||
|
|
@ -75,7 +83,7 @@
|
|||
|
||||
<% if (statistics_level == 'fine') { %>
|
||||
<div class="section">
|
||||
<h2>Message rates</h2>
|
||||
<h2>Message rates breakdown</h2>
|
||||
<div class="hider updatable">
|
||||
<table class="two-col-layout">
|
||||
<tr>
|
||||
|
|
@ -83,14 +91,12 @@
|
|||
<%= format('msg-detail-publishes',
|
||||
{'mode': 'channel',
|
||||
'object': channel.publishes,
|
||||
'label': 'Publishes',
|
||||
'totals': channel.message_stats}) %>
|
||||
'label': 'Publishes'}) %>
|
||||
</td>
|
||||
<td>
|
||||
<%= format('msg-detail-deliveries',
|
||||
{'mode': 'channel',
|
||||
'object': channel.deliveries,
|
||||
'totals': channel.message_stats}) %>
|
||||
'object': channel.deliveries}) %>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,15 @@
|
|||
|
||||
<div class="section">
|
||||
<h2>Overview</h2>
|
||||
<% if (statistics_level == 'fine') { %>
|
||||
<h3>Message rates</h3>
|
||||
<div class="box">
|
||||
<%= message_rates(exchange.message_stats_in, {'Publish': 'Publish in'}) %>
|
||||
<%= message_rates(exchange.message_stats_out, {'Publish': 'Publish out'}) %>
|
||||
</div>
|
||||
<% } %>
|
||||
|
||||
<h3>Details</h3>
|
||||
<div class="hider updatable">
|
||||
<table class="facts">
|
||||
<tr>
|
||||
|
|
@ -28,7 +37,7 @@
|
|||
|
||||
<% if (statistics_level == 'fine') { %>
|
||||
<div class="section-hidden">
|
||||
<h2>Message rates</h2>
|
||||
<h2>Message rates breakdown</h2>
|
||||
<div class="hider updatable">
|
||||
<table class="two-col-layout">
|
||||
<tr>
|
||||
|
|
@ -36,15 +45,13 @@
|
|||
<%= format('msg-detail-publishes',
|
||||
{'mode': 'exchange-incoming',
|
||||
'object': exchange.incoming,
|
||||
'label': 'Incoming <span class="help" id="exchange-rates-incoming"></span>',
|
||||
'totals': exchange.message_stats_in}) %>
|
||||
'label': 'Incoming <span class="help" id="exchange-rates-incoming"></span>'}) %>
|
||||
</td>
|
||||
<td>
|
||||
<%= format('msg-detail-publishes',
|
||||
{'mode': 'exchange-outgoing',
|
||||
'object': exchange.outgoing,
|
||||
'label': 'Outgoing <span class="help" id="exchange-rates-outgoing"></span>',
|
||||
'totals': exchange.message_stats_out}) %>
|
||||
'label': 'Outgoing <span class="help" id="exchange-rates-outgoing"></span>'}) %>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<%
|
||||
var col_redeliver = !is_col_empty(object, 'redeliver', function(o) {return o.stats;});
|
||||
%>
|
||||
<table class="list list-with-total">
|
||||
<table class="list">
|
||||
<tr>
|
||||
<% if (mode == 'queue') { %>
|
||||
<th>Channel</th>
|
||||
|
|
@ -32,11 +32,6 @@
|
|||
<td class="r"><%= fmt_rate(del.stats, 'ack') %></td>
|
||||
</tr>
|
||||
<% } %>
|
||||
<tr class="total">
|
||||
<th>Total:</th>
|
||||
<td class="r"><%= fmt_deliver_rate(totals, col_redeliver, 'mini-highlight') %></td>
|
||||
<td class="r"><%= fmt_rate(totals, 'ack', false, 'mini-highlight') %></td>
|
||||
</tr>
|
||||
</table>
|
||||
<% } else { %>
|
||||
<p> ... no deliveries ...</p>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
<h3><%= label %></h3>
|
||||
<%
|
||||
var col_return_unroutable = !is_stat_empty(totals, 'return_unroutable');
|
||||
%>
|
||||
<% if (object && object.length > 0) { %>
|
||||
<table class="list list-with-total">
|
||||
<%
|
||||
var col_return_unroutable = !is_col_empty(object, 'return_unroutable', function(o) {return o.stats;});
|
||||
%>
|
||||
<table class="list">
|
||||
<tr>
|
||||
<% if (mode == 'channel') { %>
|
||||
<th>Exchange</th>
|
||||
|
|
@ -42,14 +42,6 @@
|
|||
<% } %>
|
||||
</tr>
|
||||
<% } %>
|
||||
<tr class="total">
|
||||
<th>Total:</th>
|
||||
<td class="r"><%= fmt_rate(totals, 'publish', false, 'mini-highlight') %></td>
|
||||
<td class="r"><%= fmt_rate(totals, 'confirm', false, 'mini-highlight') %></td>
|
||||
<% if (col_return_unroutable) { %>
|
||||
<td class="r"><%= fmt_rate(totals, 'return_unroutable', false, 'mini-highlight') %></td>
|
||||
<% } %>
|
||||
</tr>
|
||||
</table>
|
||||
<% } else { %>
|
||||
<p> ... no publishes ...</p>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@
|
|||
<%= queue_length(queue, 'Unacknowledged', 'messages_unacknowledged') %>
|
||||
<%= queue_length(queue, 'Total', 'messages') %>
|
||||
</div>
|
||||
<% if (statistics_level == 'fine') { %>
|
||||
<h3>Message rates</h3>
|
||||
<div class="box">
|
||||
<%= message_rates(queue.message_stats) %>
|
||||
</div>
|
||||
<% } %>
|
||||
|
||||
<h3>Details</h3>
|
||||
<table class="facts">
|
||||
|
|
@ -85,7 +91,7 @@
|
|||
|
||||
<% if (statistics_level == 'fine') { %>
|
||||
<div class="section-hidden">
|
||||
<h2>Message rates</h2>
|
||||
<h2>Message rates breakdown</h2>
|
||||
<div class="hider updatable">
|
||||
<table class="two-col-layout">
|
||||
<tr>
|
||||
|
|
@ -93,15 +99,13 @@
|
|||
<%= format('msg-detail-publishes',
|
||||
{'mode': 'queue',
|
||||
'object': queue.incoming,
|
||||
'label': 'Incoming',
|
||||
'totals': queue.message_stats}) %>
|
||||
'label': 'Incoming'}) %>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
<%= format('msg-detail-deliveries',
|
||||
{'mode': 'queue',
|
||||
'object': queue.deliveries,
|
||||
'totals': queue.message_stats}) %>
|
||||
'object': queue.deliveries}) %>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
<%
|
||||
var mode = get_pref('rate-mode');
|
||||
var size = get_pref('chart-size');
|
||||
%>
|
||||
|
||||
<form action="#/rate-options" method="put" class="auto-submit">
|
||||
<table class="form">
|
||||
<tr>
|
||||
<th><label>Display:</label></th>
|
||||
<td>
|
||||
<select name="mode">
|
||||
<%= fmt_option('Charts', 'chart', mode) %>
|
||||
<%= fmt_option('Rates (instantaneous)', 'inst', mode) %>
|
||||
<%= fmt_option('Rates (moving average)', 'avg', mode) %>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><label>Chart size:</label></th>
|
||||
<td>
|
||||
<select name="size">
|
||||
<%= fmt_option('Small', 'small', size) %>
|
||||
<%= fmt_option('Medium', 'Medium', size) %>
|
||||
<%= fmt_option('Large', 'large', size) %>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
Loading…
Reference in New Issue