stable to default
This commit is contained in:
commit
457bb83c4d
|
|
@ -532,6 +532,82 @@
|
|||
List of network partitions this node is seeing.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>persister_read_avg_time</code></td>
|
||||
<td>
|
||||
Average wall time (milliseconds) for each disk read operation in
|
||||
the last statistics interval.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>persister_read_bytes</code></td>
|
||||
<td>
|
||||
Total number of bytes read from disk by the persister.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>persister_read_count</code></td>
|
||||
<td>
|
||||
Total number of read operations by the persister.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>persister_reopen_count</code></td>
|
||||
<td>
|
||||
Total number of times the persister has needed to recycle
|
||||
file handles between queues. In an ideal world this number
|
||||
will be zero; if the number is large, performance might be
|
||||
improved by increasing the number of file handles available
|
||||
to RabbitMQ.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>persister_seek_avg_time</code></td>
|
||||
<td>
|
||||
Average wall time (milliseconds) for each seek operation in
|
||||
the last statistics interval.
|
||||
</td>
|
||||
</tr>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>persister_seek_count</code></td>
|
||||
<td>
|
||||
Total number of seek operations by the persister.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>persister_sync_avg_time</code></td>
|
||||
<td>
|
||||
Average wall time (milliseconds) for each fsync() operation in
|
||||
the last statistics interval.
|
||||
</td>
|
||||
</tr>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>persister_sync_count</code></td>
|
||||
<td>
|
||||
Total number of fsync() operations by the persister.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>persister_write_avg_time</code></td>
|
||||
<td>
|
||||
Average wall time (milliseconds) for each disk write operation in
|
||||
the last statistics interval.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>persister_write_bytes</code></td>
|
||||
<td>
|
||||
Total number of bytes written to disk by the persister.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>persister_write_count</code></td>
|
||||
<td>
|
||||
Total number of write operations by the persister.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>proc_total</code></td>
|
||||
<td>
|
||||
|
|
|
|||
|
|
@ -12,22 +12,22 @@ function message_rates(id, stats) {
|
|||
['Get', 'get'], ['Deliver (noack)', 'deliver_no_ack'],
|
||||
['Get (noack)', 'get_no_ack'],
|
||||
['Return', 'return_unroutable']];
|
||||
return rates_chart_or_text(id, stats, items, fmt_rate, fmt_rate_large, fmt_rate_axis, true, 'Message rates', 'message-rates');
|
||||
return rates_chart_or_text(id, stats, items, fmt_rate, fmt_rate_axis, true, 'Message rates', 'message-rates');
|
||||
}
|
||||
|
||||
function queue_lengths(id, stats) {
|
||||
var items = [['Ready', 'messages_ready'],
|
||||
['Unacked', 'messages_unacknowledged'],
|
||||
['Total', 'messages']];
|
||||
return rates_chart_or_text(id, stats, items, fmt_msgs, fmt_msgs_large, fmt_num_axis, false, 'Queued messages', 'queued-messages');
|
||||
return rates_chart_or_text(id, stats, items, fmt_num_thousands, fmt_plain_axis, false, 'Queued messages', 'queued-messages');
|
||||
}
|
||||
|
||||
function data_rates(id, stats) {
|
||||
var items = [['From client', 'recv_oct'], ['To client', 'send_oct']];
|
||||
return rates_chart_or_text(id, stats, items, fmt_rate_bytes, fmt_rate_bytes_large, fmt_rate_bytes_axis, true, 'Data rates');
|
||||
return rates_chart_or_text(id, stats, items, fmt_rate_bytes, fmt_rate_bytes_axis, true, 'Data rates');
|
||||
}
|
||||
|
||||
function rates_chart_or_text(id, stats, items, chart_fmt, text_fmt, axis_fmt, chart_rates,
|
||||
function rates_chart_or_text(id, stats, items, fmt, axis_fmt, chart_rates,
|
||||
heading, heading_help) {
|
||||
var mode = get_pref('rate-mode-' + id);
|
||||
var range = get_pref('chart-range');
|
||||
|
|
@ -37,10 +37,10 @@ function rates_chart_or_text(id, stats, items, chart_fmt, text_fmt, axis_fmt, ch
|
|||
if (keys(stats).length > 0) {
|
||||
if (mode == 'chart') {
|
||||
res = rates_chart(
|
||||
id, id, items, stats, chart_fmt, axis_fmt, 'full', chart_rates);
|
||||
id, id, items, stats, fmt, axis_fmt, 'full', chart_rates);
|
||||
}
|
||||
else {
|
||||
res = rates_text(items, stats, mode, text_fmt);
|
||||
res = rates_text(items, stats, mode, fmt, chart_rates);
|
||||
}
|
||||
if (res == "") res = '<p>Waiting for data...</p>';
|
||||
}
|
||||
|
|
@ -79,7 +79,7 @@ function node_stat_count(used_key, limit_key, stats, thresholds) {
|
|||
var limit = stats[limit_key];
|
||||
if (typeof used == 'number') {
|
||||
return node_stat(used_key, 'Used', limit_key, 'available', stats,
|
||||
fmt_num_obj, fmt_num_axis,
|
||||
fmt_plain, fmt_plain_axis,
|
||||
fmt_color(used / limit, thresholds));
|
||||
} else {
|
||||
return used;
|
||||
|
|
@ -91,19 +91,20 @@ function node_stat_count_bar(used_key, limit_key, stats, thresholds) {
|
|||
var limit = stats[limit_key];
|
||||
if (typeof used == 'number') {
|
||||
return node_stat_bar(used_key, limit_key, 'available', stats,
|
||||
fmt_num_axis, fmt_color(used / limit, thresholds));
|
||||
fmt_plain_axis,
|
||||
fmt_color(used / limit, thresholds));
|
||||
} else {
|
||||
return used;
|
||||
}
|
||||
}
|
||||
|
||||
function node_stat(used_key, used_name, limit_key, suffix, stats, rate_fmt,
|
||||
function node_stat(used_key, used_name, limit_key, suffix, stats, fmt,
|
||||
axis_fmt, colour, help, invert) {
|
||||
if (get_pref('rate-mode-node-stats') == 'chart') {
|
||||
var items = [[used_name, used_key], ['Limit', limit_key]];
|
||||
add_fake_limit_details(used_key, limit_key, stats);
|
||||
return rates_chart('node-stats', 'node-stats-' + used_key, items, stats,
|
||||
rate_fmt, axis_fmt, 'node', false);
|
||||
fmt, axis_fmt, 'node', false);
|
||||
} else {
|
||||
return node_stat_bar(used_key, limit_key, suffix, stats, axis_fmt,
|
||||
colour, help, invert);
|
||||
|
|
@ -156,7 +157,7 @@ function node_stats_prefs() {
|
|||
return chart_h3('node-stats', 'Node statistics');
|
||||
}
|
||||
|
||||
function rates_chart(type_id, id, items, stats, rate_fmt, axis_fmt, type,
|
||||
function rates_chart(type_id, id, items, stats, fmt, axis_fmt, type,
|
||||
chart_rates) {
|
||||
function show(key) {
|
||||
return get_pref('chart-line-' + id + key) === 'true';
|
||||
|
|
@ -177,9 +178,11 @@ function rates_chart(type_id, id, items, stats, rate_fmt, axis_fmt, type,
|
|||
chart_data[id]['data'][name] = stats[key_details];
|
||||
chart_data[id]['data'][name].ix = ix;
|
||||
}
|
||||
var value = chart_rates ? pick_rate(fmt, stats, key) :
|
||||
pick_abs(fmt, stats, key);
|
||||
legend.push({name: name,
|
||||
key: key,
|
||||
value: rate_fmt(stats, key),
|
||||
value: value,
|
||||
show: show(key)});
|
||||
ix++;
|
||||
}
|
||||
|
|
@ -201,7 +204,7 @@ function rates_chart(type_id, id, items, stats, rate_fmt, axis_fmt, type,
|
|||
return legend.length > 0 ? html : '';
|
||||
}
|
||||
|
||||
function rates_text(items, stats, mode, rate_fmt) {
|
||||
function rates_text(items, stats, mode, fmt, chart_rates) {
|
||||
var res = '';
|
||||
for (var i in items) {
|
||||
var name = items[i][0];
|
||||
|
|
@ -209,9 +212,10 @@ function rates_text(items, stats, mode, rate_fmt) {
|
|||
var key_details = key + '_details';
|
||||
if (key_details in stats) {
|
||||
var details = stats[key_details];
|
||||
res += '<div class="highlight">' + name;
|
||||
res += rate_fmt(stats, key, mode);
|
||||
res += '</div>';
|
||||
res += '<div class="highlight">' + name + '<strong>';
|
||||
res += chart_rates ? pick_rate(fmt, stats, key, mode) :
|
||||
pick_abs(fmt, stats, key, mode);
|
||||
res += '</strong></div>';
|
||||
}
|
||||
}
|
||||
return res == '' ? '' : '<div class="box">' + res + '</div>';
|
||||
|
|
|
|||
|
|
@ -12,11 +12,6 @@ function fmt_string(str, unknown) {
|
|||
return fmt_escape_html("" + str);
|
||||
}
|
||||
|
||||
function fmt_bytes(bytes) {
|
||||
if (bytes == undefined) return UNKNOWN_REPR;
|
||||
return fmt_si_prefix(bytes, bytes, 1024, false) + 'B';
|
||||
}
|
||||
|
||||
function fmt_si_prefix(num0, max0, thousand, allow_fractions) {
|
||||
if (num == 0) return 0;
|
||||
|
||||
|
|
@ -228,71 +223,51 @@ function fmt_percent(num) {
|
|||
}
|
||||
}
|
||||
|
||||
function fmt_rate(obj, name, mode) {
|
||||
var raw = fmt_rate0(obj, name, mode, fmt_rate_num);
|
||||
return raw == '' ? '' : (raw + '/s');
|
||||
}
|
||||
|
||||
function fmt_rate_bytes(obj, name, mode) {
|
||||
var raw = fmt_rate0(obj, name, mode, fmt_bytes);
|
||||
return raw == '' ? '' : (raw + '/s' +
|
||||
'<sub>(' + fmt_bytes(obj[name]) + ' total)</sub>');
|
||||
}
|
||||
|
||||
function fmt_bytes_obj(obj, name, mode) {
|
||||
return fmt_bytes(obj[name]);
|
||||
}
|
||||
|
||||
function fmt_num_obj(obj, name, mode) {
|
||||
return obj[name];
|
||||
}
|
||||
|
||||
function fmt_rate_large(obj, name, mode) {
|
||||
return '<strong>' + fmt_rate0(obj, name, mode, fmt_rate_num) +
|
||||
'</strong>msg/s';
|
||||
}
|
||||
|
||||
function fmt_rate_bytes_large(obj, name, mode) {
|
||||
return '<strong>' + fmt_rate0(obj, name, mode, fmt_bytes) + '/s</strong>' +
|
||||
'(' + fmt_bytes(obj[name]) + ' total)';
|
||||
}
|
||||
|
||||
function fmt_rate0(obj, name, mode, fmt) {
|
||||
function pick_rate(fmt, obj, name, mode) {
|
||||
if (obj == undefined || obj[name] == undefined ||
|
||||
obj[name + '_details'] == undefined) return '';
|
||||
var details = obj[name + '_details'];
|
||||
return fmt(mode == 'avg' ? details.avg_rate : details.rate);
|
||||
}
|
||||
|
||||
function fmt_msgs(obj, name, mode) {
|
||||
return fmt_msgs0(obj, name, mode) + ' msg';
|
||||
}
|
||||
|
||||
function fmt_msgs_large(obj, name, mode) {
|
||||
return '<strong>' + fmt_msgs0(obj, name, mode) + '</strong>' +
|
||||
fmt_rate0(obj, name, mode, fmt_msgs_rate);
|
||||
}
|
||||
|
||||
function fmt_msgs0(obj, name, mode) {
|
||||
function pick_abs(fmt, obj, name, mode) {
|
||||
if (obj == undefined || obj[name] == undefined ||
|
||||
obj[name + '_details'] == undefined) return '';
|
||||
var details = obj[name + '_details'];
|
||||
return mode == 'avg' ? fmt_rate_num(details.avg) :
|
||||
fmt_num_thousands(obj[name]);
|
||||
return fmt(mode == 'avg' ? details.avg : obj[name]);
|
||||
}
|
||||
|
||||
function fmt_msgs_rate(num) {
|
||||
if (num > 0) return '+' + fmt_rate_num(num) + ' msg/s';
|
||||
else if (num < 0) return '-' + fmt_rate_num(-num) + ' msg/s';
|
||||
else return ' ';
|
||||
function fmt_detail_rate(obj, name, mode) {
|
||||
return pick_rate(fmt_rate, name, mode);
|
||||
}
|
||||
|
||||
function fmt_detail_rate_bytes(obj, name, mode) {
|
||||
return pick_rate(fmt_rate_bytes, name, mode);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
// These are pluggable for charts etc
|
||||
|
||||
function fmt_plain(num) {
|
||||
return num;
|
||||
}
|
||||
|
||||
function fmt_plain_axis(num, max) {
|
||||
return fmt_si_prefix(num, max, 1000, true);
|
||||
}
|
||||
|
||||
function fmt_rate(num) {
|
||||
return fmt_rate_num(num) + '/s';
|
||||
}
|
||||
|
||||
function fmt_rate_axis(num, max) {
|
||||
return fmt_si_prefix(num, max, 1000, true) + '/s';
|
||||
return fmt_plain_axis(num, max) + '/s';
|
||||
}
|
||||
|
||||
function fmt_num_axis(num, max) {
|
||||
return fmt_si_prefix(num, max, 1000, true);
|
||||
function fmt_bytes(bytes) {
|
||||
if (bytes == undefined) return UNKNOWN_REPR;
|
||||
return fmt_si_prefix(bytes, bytes, 1024, false) + 'B';
|
||||
}
|
||||
|
||||
function fmt_bytes_axis(num, max) {
|
||||
|
|
@ -300,11 +275,20 @@ function fmt_bytes_axis(num, max) {
|
|||
return fmt_bytes(isNaN(num) ? 0 : num);
|
||||
}
|
||||
|
||||
function fmt_rate_bytes(num) {
|
||||
return fmt_bytes(num) + '/s';
|
||||
}
|
||||
|
||||
function fmt_rate_bytes_axis(num, max) {
|
||||
return fmt_bytes_axis(num, max) + '/s';
|
||||
}
|
||||
|
||||
function fmt_ms(num) {
|
||||
return fmt_rate_num(num) + 'ms';
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
function fmt_maybe_vhost(name) {
|
||||
return vhosts_interesting ?
|
||||
' in virtual host <b>' + fmt_escape_html(name) + '</b>'
|
||||
|
|
|
|||
|
|
@ -137,6 +137,7 @@ var COLUMNS =
|
|||
// All these are to do with hiding UI elements if
|
||||
var rates_mode; // ...there are no fine stats
|
||||
var user_administrator; // ...user is not an admin
|
||||
var user_policymaker; // ...user is not a policymaker
|
||||
var user_monitor; // ...user cannot monitor
|
||||
var nodes_interesting; // ...we are not in a cluster
|
||||
var vhosts_interesting; // ...there is only one vhost
|
||||
|
|
@ -164,6 +165,7 @@ function setup_global_vars() {
|
|||
rates_mode = overview.rates_mode;
|
||||
user_tags = expand_user_tags(user.tags.split(","));
|
||||
user_administrator = jQuery.inArray("administrator", user_tags) != -1;
|
||||
user_policymaker = jQuery.inArray("policymaker", user_tags) != -1;
|
||||
user_monitor = jQuery.inArray("monitoring", user_tags) != -1;
|
||||
replace_content('login-details',
|
||||
'<p>User: <b>' + user.name + '</b></p>' +
|
||||
|
|
|
|||
|
|
@ -251,6 +251,28 @@ HELP = {
|
|||
'plugins' :
|
||||
'Note that only plugins which are both explicitly enabled and running are shown here.',
|
||||
|
||||
'io-operations':
|
||||
'Rate of I/O operations. Only operations performed by the message \
|
||||
persister are shown here (e.g. metadata changes in Mnesia or writes \
|
||||
to the log files are not shown).\
|
||||
<dl>\
|
||||
<dt>Read</dt>\
|
||||
<dd>Rate at which data is read from the disk.</dd>\
|
||||
<dt>Write</dt>\
|
||||
<dd>Rate at which data is written to the disk.</dd>\
|
||||
<dt>Seek</dt>\
|
||||
<dd>Rate at which the broker switches position while reading or \
|
||||
writing to disk.</dd>\
|
||||
<dt>Sync</dt>\
|
||||
<dd>Rate at which the broker invokes <code>fsync()</code> to ensure \
|
||||
data is flushed to disk.</dd>\
|
||||
<dt>Reopen</dt>\
|
||||
<dd>Rate at which the broker recycles file handles in order to support \
|
||||
more queues than it has file handles. If this operation is occurring \
|
||||
frequently you may get a performance boost from increasing the number \
|
||||
of file handles available.</dd>\
|
||||
</dl>',
|
||||
|
||||
'foo': 'foo' // No comma.
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -167,22 +167,22 @@
|
|||
<% } %>
|
||||
<% if (rates_mode != 'none') { %>
|
||||
<% if (show_column('channels', 'rate-publish')) { %>
|
||||
<td class="r"><%= fmt_rate(channel.message_stats, 'publish') %></td>
|
||||
<td class="r"><%= fmt_detail_rate(channel.message_stats, 'publish') %></td>
|
||||
<% } %>
|
||||
<% if (show_column('channels', 'rate-confirm')) { %>
|
||||
<td class="r"><%= fmt_rate(channel.message_stats, 'confirm') %></td>
|
||||
<td class="r"><%= fmt_detail_rate(channel.message_stats, 'confirm') %></td>
|
||||
<% } %>
|
||||
<% if (show_column('channels', 'rate-return')) { %>
|
||||
<td class="r"><%= fmt_rate(channel.message_stats, 'return_unroutable') %></td>
|
||||
<td class="r"><%= fmt_detail_rate(channel.message_stats, 'return_unroutable') %></td>
|
||||
<% } %>
|
||||
<% if (show_column('channels', 'rate-deliver')) { %>
|
||||
<td class="r"><%= fmt_rate(channel.message_stats, 'deliver_get') %></td>
|
||||
<td class="r"><%= fmt_detail_rate(channel.message_stats, 'deliver_get') %></td>
|
||||
<% } %>
|
||||
<% if (show_column('channels', 'rate-redeliver')) { %>
|
||||
<td class="r"><%= fmt_rate(channel.message_stats, 'redeliver') %></td>
|
||||
<td class="r"><%= fmt_detail_rate(channel.message_stats, 'redeliver') %></td>
|
||||
<% } %>
|
||||
<% if (show_column('channels', 'rate-ack')) { %>
|
||||
<td class="r"><%= fmt_rate(channel.message_stats, 'ack') %></td>
|
||||
<td class="r"><%= fmt_detail_rate(channel.message_stats, 'ack') %></td>
|
||||
<% } %>
|
||||
<% } %>
|
||||
</tr>
|
||||
|
|
|
|||
|
|
@ -115,10 +115,10 @@
|
|||
<td><%= fmt_client_name(connection.client_properties) %></td>
|
||||
<% } %>
|
||||
<% if (show_column('connections', 'from_client')) { %>
|
||||
<td><%= fmt_rate_bytes(connection, 'recv_oct') %></td>
|
||||
<td><%= fmt_detail_rate_bytes(connection, 'recv_oct') %></td>
|
||||
<% } %>
|
||||
<% if (show_column('connections', 'to_client')) { %>
|
||||
<td><%= fmt_rate_bytes(connection, 'send_oct') %></td>
|
||||
<td><%= fmt_detail_rate_bytes(connection, 'send_oct') %></td>
|
||||
<% } %>
|
||||
<% if (show_column('connections', 'heartbeat')) { %>
|
||||
<td class="r"><%= fmt_time(connection.timeout, 's') %></td>
|
||||
|
|
|
|||
|
|
@ -64,10 +64,10 @@
|
|||
<% } %>
|
||||
<% if (rates_mode != 'none') { %>
|
||||
<% if (show_column('exchanges', 'rate-in')) { %>
|
||||
<td class="r"><%= fmt_rate(exchange.message_stats, 'publish_in') %></td>
|
||||
<td class="r"><%= fmt_detail_rate(exchange.message_stats, 'publish_in') %></td>
|
||||
<% } %>
|
||||
<% if (show_column('exchanges', 'rate-out')) { %>
|
||||
<td class="r"><%= fmt_rate(exchange.message_stats, 'publish_out') %></td>
|
||||
<td class="r"><%= fmt_detail_rate(exchange.message_stats, 'publish_out') %></td>
|
||||
<% } %>
|
||||
<% } %>
|
||||
</tr>
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@
|
|||
<% } else { %>
|
||||
<td><%= link_queue(del.queue.vhost, del.queue.name) %></td>
|
||||
<% } %>
|
||||
<td class="r"><%= fmt_rate(del.stats, 'deliver_get') %></td>
|
||||
<td class="r"><%= fmt_rate(del.stats, 'ack') %></td>
|
||||
<td class="r"><%= fmt_detail_rate(del.stats, 'deliver_get') %></td>
|
||||
<td class="r"><%= fmt_detail_rate(del.stats, 'ack') %></td>
|
||||
</tr>
|
||||
<% } %>
|
||||
</table>
|
||||
|
|
|
|||
|
|
@ -34,9 +34,9 @@
|
|||
<% } else { %>
|
||||
<td><%= link_exchange(pub.exchange.vhost, pub.exchange.name) %></td>
|
||||
<% } %>
|
||||
<td class="r"><%= fmt_rate(pub.stats, 'publish') %></td>
|
||||
<td class="r"><%= fmt_detail_rate(pub.stats, 'publish') %></td>
|
||||
<% if (col_confirm) { %>
|
||||
<td class="r"><%= fmt_rate(pub.stats, 'confirm') %></td>
|
||||
<td class="r"><%= fmt_detail_rate(pub.stats, 'confirm') %></td>
|
||||
<% } %>
|
||||
</tr>
|
||||
<% } %>
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@
|
|||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h2>Statistics</h2>
|
||||
<h2>Process Statistics</h2>
|
||||
<div class="hider">
|
||||
<% if (!node.running) { %>
|
||||
<p class="warning">Node not running</p>
|
||||
|
|
@ -106,7 +106,7 @@
|
|||
<td>
|
||||
<% if (node.mem_limit != 'memory_monitoring_disabled') { %>
|
||||
<%= node_stat('mem_used', 'Used', 'mem_limit', 'high watermark', node,
|
||||
fmt_bytes_obj, fmt_bytes_axis,
|
||||
fmt_bytes, fmt_bytes_axis,
|
||||
node.mem_alarm ? 'red' : 'green',
|
||||
node.mem_alarm ? 'memory-alarm' : null) %>
|
||||
<% } else { %>
|
||||
|
|
@ -121,7 +121,7 @@
|
|||
<td>
|
||||
<% if (node.disk_free_limit != 'disk_free_monitoring_disabled') { %>
|
||||
<%= node_stat('disk_free', 'Free', 'disk_free_limit', 'low watermark', node,
|
||||
fmt_bytes_obj, fmt_bytes_axis,
|
||||
fmt_bytes, fmt_bytes_axis,
|
||||
node.disk_free_alarm ? 'red' : 'green',
|
||||
node.disk_free_alarm ? 'disk_free-alarm' : null,
|
||||
true) %>
|
||||
|
|
@ -137,6 +137,25 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h2>I/O Statistics</h2>
|
||||
<div class="hider">
|
||||
<% if (!node.running) { %>
|
||||
<p class="warning">Node not running</p>
|
||||
<% } else if (node.os_pid == undefined) { %>
|
||||
<p class="warning">Node statistics not available</p>
|
||||
<% } else { %>
|
||||
<%= rates_chart_or_text('persister-stats-count', node, [['Read', 'persister_read_count'], ['Write', 'persister_write_count'], ['Seek', 'persister_seek_count'], ['Sync', 'persister_sync_count'], ['Reopen', 'persister_reopen_count']], fmt_rate, fmt_rate_axis, true, 'Operations', 'io-operations') %>
|
||||
|
||||
<%= rates_chart_or_text('persister-stats-bytes', node, [['Read', 'persister_read_bytes'], ['Write', 'persister_write_bytes']], fmt_rate_bytes, fmt_rate_bytes_axis, true, 'Data rates') %>
|
||||
|
||||
<%= rates_chart_or_text('persister-stats-time', node, [['Read', 'persister_read_avg_time'], ['Write', 'persister_write_avg_time'], ['Seek', 'persister_seek_avg_time'], ['Sync', 'persister_sync_avg_time']], fmt_ms, fmt_ms, false, 'Average time per operation') %>
|
||||
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="section">
|
||||
<h2>Memory details</h2>
|
||||
<div class="hider">
|
||||
|
|
|
|||
|
|
@ -245,6 +245,51 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<% if (user_policymaker) { %>
|
||||
<div class="section-hidden">
|
||||
<h2>Move messages</h2>
|
||||
<div class="hider">
|
||||
<% if (NAVIGATION['Admin'][0]['Shovel Management'] == undefined) { %>
|
||||
<p>To move messages, the shovel plugin must be enabled, try:</p>
|
||||
<pre>$ rabbitmq-plugins enable rabbitmq_shovel rabbitmq_shovel_management</pre>
|
||||
<% } else { %>
|
||||
<p>
|
||||
The shovel plugin can be used to move messages from this queue
|
||||
to another one. The form below will create a temporary shovel to
|
||||
move messages to another queue on the same virtual host, with
|
||||
default settings.
|
||||
</p>
|
||||
<p>
|
||||
For more options <a href="#/dynamic-shovels">see the shovel
|
||||
interface</a>.
|
||||
</p>
|
||||
<form action="#/shovel-parameters" method="put">
|
||||
<input type="hidden" name="component" value="shovel"/>
|
||||
<input type="hidden" name="vhost" value="<%= fmt_string(queue.vhost) %>"/>
|
||||
<input type="hidden" name="name" value="Move from <%= fmt_string(queue.name) %>"/>
|
||||
<input type="hidden" name="src-uri" value="amqp:///<%= esc(queue.vhost) %>"/>
|
||||
<input type="hidden" name="src-queue" value="<%= fmt_string(queue.name) %>"/>
|
||||
|
||||
<input type="hidden" name="dest-uri" value="amqp:///<%= esc(queue.vhost) %>"/>
|
||||
<input type="hidden" name="prefetch-count" value="1000"/>
|
||||
<input type="hidden" name="add-forward-headers" value="false"/>
|
||||
<input type="hidden" name="ack-mode" value="on-confirm"/>
|
||||
<input type="hidden" name="delete-after" value="queue-length"/>
|
||||
<input type="hidden" name="redirect" value="#/queues"/>
|
||||
|
||||
<table class="form">
|
||||
<tr>
|
||||
<th>Destination queue:</th>
|
||||
<td><input type="text" name="dest-queue"/></td>
|
||||
</tr>
|
||||
</table>
|
||||
<input type="submit" value="Move messages"/>
|
||||
</form>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
|
||||
<div class="section-hidden">
|
||||
<h2>Delete / purge</h2>
|
||||
<div class="hider">
|
||||
|
|
|
|||
|
|
@ -160,16 +160,16 @@
|
|||
<% } %>
|
||||
<% if (rates_mode != 'none') { %>
|
||||
<% if (show_column('queues', 'rate-incoming')) { %>
|
||||
<td class="r"><%= fmt_rate(queue.message_stats, 'publish') %></td>
|
||||
<td class="r"><%= fmt_detail_rate(queue.message_stats, 'publish') %></td>
|
||||
<% } %>
|
||||
<% if (show_column('queues', 'rate-deliver')) { %>
|
||||
<td class="r"><%= fmt_rate(queue.message_stats, 'deliver_get') %></td>
|
||||
<td class="r"><%= fmt_detail_rate(queue.message_stats, 'deliver_get') %></td>
|
||||
<% } %>
|
||||
<% if (show_column('queues', 'rate-redeliver')) { %>
|
||||
<td class="r"><%= fmt_rate(queue.message_stats, 'redeliver') %></td>
|
||||
<td class="r"><%= fmt_detail_rate(queue.message_stats, 'redeliver') %></td>
|
||||
<% } %>
|
||||
<% if (show_column('queues', 'rate-ack')) { %>
|
||||
<td class="r"><%= fmt_rate(queue.message_stats, 'ack') %></td>
|
||||
<td class="r"><%= fmt_detail_rate(queue.message_stats, 'ack') %></td>
|
||||
<% } %>
|
||||
<% } %>
|
||||
</tr>
|
||||
|
|
|
|||
|
|
@ -64,17 +64,17 @@
|
|||
<td class="r"><%= fmt_num_thousands(vhost.messages) %></td>
|
||||
<% } %>
|
||||
<% if (show_column('vhosts', 'from_client')) { %>
|
||||
<td><%= fmt_rate_bytes(vhost, 'recv_oct') %></td>
|
||||
<td><%= fmt_detail_rate_bytes(vhost, 'recv_oct') %></td>
|
||||
<% } %>
|
||||
<% if (show_column('vhosts', 'to_client')) { %>
|
||||
<td><%= fmt_rate_bytes(vhost, 'send_oct') %></td>
|
||||
<td><%= fmt_detail_rate_bytes(vhost, 'send_oct') %></td>
|
||||
<% } %>
|
||||
<% if (rates_mode != 'none') { %>
|
||||
<% if (show_column('vhosts', 'rate-publish')) { %>
|
||||
<td class="r"><%= fmt_rate(vhost.message_stats, 'publish') %></td>
|
||||
<td class="r"><%= fmt_detail_rate(vhost.message_stats, 'publish') %></td>
|
||||
<% } %>
|
||||
<% if (show_column('vhosts', 'rate-deliver')) { %>
|
||||
<td class="r"><%= fmt_rate(vhost.message_stats, 'deliver_get') %></td>
|
||||
<td class="r"><%= fmt_detail_rate(vhost.message_stats, 'deliver_get') %></td>
|
||||
<% } %>
|
||||
<% } %>
|
||||
</tr>
|
||||
|
|
|
|||
|
|
@ -159,7 +159,19 @@
|
|||
[messages, messages_ready, messages_unacknowledged]).
|
||||
|
||||
-define(COARSE_NODE_STATS,
|
||||
[mem_used, fd_used, sockets_used, proc_used, disk_free]).
|
||||
[mem_used, fd_used, sockets_used, proc_used, disk_free,
|
||||
persister_read_count, persister_read_bytes, persister_read_avg_time,
|
||||
persister_write_count, persister_write_bytes, persister_write_avg_time,
|
||||
persister_sync_count, persister_sync_avg_time,
|
||||
persister_seek_count, persister_seek_avg_time,
|
||||
persister_reopen_count]).
|
||||
|
||||
%% Normally 0 and no history means "has never happened, don't
|
||||
%% report". But for these things we do want to report even at 0 with
|
||||
%% no history.
|
||||
-define(ALWAYS_REPORT_STATS,
|
||||
[persister_read_avg_time, persister_write_avg_time,
|
||||
persister_sync_avg_time | ?COARSE_QUEUE_STATS]).
|
||||
|
||||
-define(COARSE_CONN_STATS, [recv_oct, send_oct]).
|
||||
|
||||
|
|
@ -572,8 +584,10 @@ handle_event(#event{type = consumer_deleted, props = Props}, State) ->
|
|||
%% TODO: we don't clear up after dead nodes here - this is a very tiny
|
||||
%% leak every time a node is permanently removed from the cluster. Do
|
||||
%% we care?
|
||||
handle_event(#event{type = node_stats, props = Stats, timestamp = Timestamp},
|
||||
handle_event(#event{type = node_stats, props = Stats0, timestamp = Timestamp},
|
||||
State) ->
|
||||
Stats = proplists:delete(persister_stats, Stats0) ++
|
||||
pget(persister_stats, Stats0),
|
||||
handle_stats(node_stats, Stats, Timestamp, [], ?COARSE_NODE_STATS, State);
|
||||
|
||||
handle_event(_Event, State) ->
|
||||
|
|
@ -965,7 +979,7 @@ format_detail_id(#resource{name = Name, virtual_host = Vhost, kind = Kind},
|
|||
format_samples(Ranges, ManyStats, #state{interval = Interval}) ->
|
||||
lists:append(
|
||||
[case rabbit_mgmt_stats:is_blank(Stats) andalso
|
||||
not lists:member(K, ?COARSE_QUEUE_STATS) of
|
||||
not lists:member(K, ?ALWAYS_REPORT_STATS) of
|
||||
true -> [];
|
||||
false -> {Details, Counter} = rabbit_mgmt_stats:format(
|
||||
pick_range(K, Ranges),
|
||||
|
|
@ -1095,7 +1109,7 @@ gc_batch(State = #state{aggregated_stats = ETS}) ->
|
|||
gc_batch(0, _Policies, State) ->
|
||||
State;
|
||||
gc_batch(Rows, Policies, State = #state{aggregated_stats = ETS,
|
||||
gc_next_key = Key0}) ->
|
||||
gc_next_key = Key0}) ->
|
||||
Key = case Key0 of
|
||||
undefined -> ets:first(ETS);
|
||||
_ -> ets:next(ETS, Key0)
|
||||
|
|
|
|||
|
|
@ -157,9 +157,8 @@ internal_user(User) ->
|
|||
{tags, tags(User#internal_user.tags)}].
|
||||
|
||||
user(User) ->
|
||||
[{name, User#user.username},
|
||||
{tags, tags(User#user.tags)},
|
||||
{auth_backend, User#user.auth_backend}].
|
||||
[{name, User#user.username},
|
||||
{tags, tags(User#user.tags)}].
|
||||
|
||||
tags(Tags) ->
|
||||
list_to_binary(string:join([atom_to_list(T) || T <- Tags], ",")).
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
-export([with_channel/4, with_channel/5]).
|
||||
-export([props_to_method/2, props_to_method/4]).
|
||||
-export([all_or_one_vhost/2, http_to_amqp/5, reply/3, filter_vhost/3]).
|
||||
-export([filter_conn_ch_list/3, filter_user/2, list_login_vhosts/1]).
|
||||
-export([filter_conn_ch_list/3, filter_user/2, list_login_vhosts/2]).
|
||||
-export([with_decode/5, decode/1, decode/2, redirect/2, set_resp_header/3,
|
||||
args/1]).
|
||||
-export([reply_list/3, reply_list/4, sort_list/2, destination_type/1]).
|
||||
|
|
@ -77,7 +77,7 @@ user_matches_vhost(ReqData, User) ->
|
|||
case vhost(ReqData) of
|
||||
not_found -> true;
|
||||
none -> true;
|
||||
V -> lists:member(V, list_login_vhosts(User))
|
||||
V -> lists:member(V, list_login_vhosts(User, peersock(ReqData)))
|
||||
end.
|
||||
|
||||
%% Used for connections / channels. A normal user can only see / delete
|
||||
|
|
@ -143,12 +143,15 @@ is_authorized(ReqData, Context, Username, Password, ErrorMsg, Fun) ->
|
|||
not_authorised(<<"Login failed">>, ReqData, Context)
|
||||
end.
|
||||
|
||||
%% We can't use wrq:peer/1 because that trusts X-Forwarded-For.
|
||||
peer(ReqData) ->
|
||||
WMState = ReqData#wm_reqdata.wm_state,
|
||||
{ok, {IP,_Port}} = peername(WMState#wm_reqstate.socket),
|
||||
{ok, {IP,_Port}} = peername(peersock(ReqData)),
|
||||
IP.
|
||||
|
||||
%% We can't use wrq:peer/1 because that trusts X-Forwarded-For.
|
||||
peersock(ReqData) ->
|
||||
WMState = ReqData#wm_reqdata.wm_state,
|
||||
WMState#wm_reqstate.socket.
|
||||
|
||||
%% Like the one in rabbit_net, but we and webmachine have a different
|
||||
%% way of wrapping
|
||||
peername(Sock) when is_port(Sock) -> inet:peername(Sock);
|
||||
|
|
@ -452,6 +455,8 @@ with_channel(VHost, ReqData,
|
|||
end;
|
||||
{error, {auth_failure, Msg}} ->
|
||||
not_authorised(Msg, ReqData, Context);
|
||||
{error, access_refused} ->
|
||||
not_authorised(<<"Access refused.">>, ReqData, Context);
|
||||
{error, {nodedown, N}} ->
|
||||
bad_request(
|
||||
list_to_binary(
|
||||
|
|
@ -470,8 +475,8 @@ all_or_one_vhost(ReqData, Fun) ->
|
|||
VHost -> Fun(VHost)
|
||||
end.
|
||||
|
||||
filter_vhost(List, _ReqData, Context) ->
|
||||
VHosts = list_login_vhosts(Context#context.user),
|
||||
filter_vhost(List, ReqData, Context) ->
|
||||
VHosts = list_login_vhosts(Context#context.user, peersock(ReqData)),
|
||||
[I || I <- List, lists:member(pget(vhost, I), VHosts)].
|
||||
|
||||
filter_user(List, _ReqData, #context{user = User}) ->
|
||||
|
|
@ -533,12 +538,12 @@ intersects(A, B) -> lists:any(fun(I) -> lists:member(I, B) end, A).
|
|||
list_visible_vhosts(User = #user{tags = Tags}) ->
|
||||
case is_monitor(Tags) of
|
||||
true -> rabbit_vhost:list();
|
||||
false -> list_login_vhosts(User)
|
||||
false -> list_login_vhosts(User, undefined)
|
||||
end.
|
||||
|
||||
list_login_vhosts(User) ->
|
||||
list_login_vhosts(User, Sock) ->
|
||||
[V || V <- rabbit_vhost:list(),
|
||||
case catch rabbit_access_control:check_vhost_access(User, V) of
|
||||
case catch rabbit_access_control:check_vhost_access(User, V, Sock) of
|
||||
ok -> true;
|
||||
_ -> false
|
||||
end].
|
||||
|
|
|
|||
Loading…
Reference in New Issue