Start of a process details page

This commit is contained in:
Simon MacMullen 2013-12-11 17:23:29 +00:00
parent a4063718c8
commit fb974db8a1
6 changed files with 124 additions and 21 deletions

View File

@ -0,0 +1,30 @@
<h1>Process: <b><%= fmt_string(process.pid) %></b></h1>
<div class="updatable">
<table class="facts">
<tr>
<th>Description</th>
<td><%= fmt_process_name(process) %></td>
</tr>
<tr>
<th>Description type</th>
<td><%= fmt_remove_rabbit_prefix(process.name.type) %></td>
</tr>
<tr>
<th>Memory</th>
<td><%= fmt_bytes(process.memory) %></td>
</tr>
<tr>
<th>Message queue length</th>
<td><%= process.message_queue_len %></td>
</tr>
<tr>
<th>Total reductions</th>
<td><%= process.reductions %></td>
</tr>
<tr>
<th>Status</th>
<td><%= process.status %></td>
</tr>
</table>
</div>

View File

@ -1,7 +1,8 @@
<table class="list updatable">
<thead>
<tr>
<th>Name</th>
<th>Process</th>
<th>Description</th>
<th><%= fmt_sort('Memory', 'memory') %></th>
<th><%= fmt_sort('Reductions / sec', 'reductions') %></th>
<th>Message queue</th>
@ -14,7 +15,11 @@
var process = processes[i];
%>
<tr<%= alt_rows(i)%>>
<td><%= fmt_process_name(process) %></td>
<td><%= link_pid(process.pid) %></td>
<td>
<%= fmt_process_name(process) %>
<sub><%= fmt_remove_rabbit_prefix(process.name.type) %></sub>
</td>
<td><%= fmt_bytes(process.memory * 1.0) %></td>
<td class="r"><%= process.reduction_delta %></td>
<td class="r"><%= process.message_queue_len %></td>

View File

@ -1,36 +1,41 @@
dispatcher_add(function(sammy) {
sammy.get('#/top', function() {
render({'top': {path: '/top',
options: {sort:true}}},
'top', '#/top');
});
sammy.get('#/top', function() {
render({'top': {path: '/top',
options: {sort:true}}},
'top', '#/top');
});
sammy.get('#/top/:pid', function() {
render({'process': '/top/' + esc(this.params['pid'])},
'process', '#/top');
});
});
NAVIGATION['Admin'][0]['Top'] = ['#/top', 'administrator'];
function link_pid(name) {
return _link_to(name, '#/top/' + esc(name))
}
function fmt_process_name(process) {
if (process == undefined) return '';
var name = process.name;
var txt;
if (name.supertype != undefined) {
if (name.supertype == 'channel') {
txt = link_channel(name.connection_name + ' (' +
name.channel_number + ')');
return link_channel(name.connection_name + ' (' +
name.channel_number + ')');
}
else if (name.supertype == 'queue') {
txt = link_queue(name.vhost, name.queue_name);
return link_queue(name.vhost, name.queue_name);
}
else if (name.supertype == 'connection') {
txt = link_conn(name.connection_name);
return link_conn(name.connection_name);
}
}
else {
txt = name.name;
return '<b>' + name.name + '</b>';
}
return txt + '<sub>' + fmt_remove_rabbit_prefix(name.type) + '</sub>';
}
function fmt_remove_rabbit_prefix(name) {

View File

@ -20,5 +20,6 @@
-export([dispatcher/0, web_ui/0]).
dispatcher() -> [{["top"], rabbit_top_wm_processes, []}].
dispatcher() -> [{["top"], rabbit_top_wm_processes, []},
{["top", pid], rabbit_top_wm_process, []}].
web_ui() -> [{javascript, <<"top.js">>}].

View File

@ -18,7 +18,7 @@
-include_lib("rabbit_common/include/rabbit.hrl").
-export([toplist/3]).
-export([toplist/3, obtain_name/1]).
toplist(Key, Count, List) ->
Sorted = lists:sublist(
@ -35,7 +35,7 @@ fmt_all(Info) ->
[{name, obtain_name(Pid)} | [{K, fmt(V)} || {K, V} <- Info]].
fmt(Pid) when is_pid(Pid) ->
list_to_binary(rabbit_misc:pid_to_string(Pid));
list_to_binary(pid_to_list(Pid));
fmt(Other) ->
list_to_binary(rabbit_misc:format("~p", [Other])).
@ -88,9 +88,9 @@ obtain_from_initial_call(Pid) ->
fail -> [{type, unidentified},
{name, fmt(Pid)}];
MFA -> case guess_initial_call(MFA) of
fail -> [{type, initial_call_guess},
fail -> [{type, guessed},
{name, fmt(MFA)}];
Name -> [{type, initial_call},
Name -> [{type, known},
{name, Name}]
end
end.

View File

@ -0,0 +1,62 @@
%% The contents of this file are subject to the Mozilla Public License
%% Version 1.1 (the "License"); you may not use this file except in
%% compliance with the License. You may obtain a copy of the License
%% at http://www.mozilla.org/MPL/
%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and
%% limitations under the License.
%%
%% The Original Code is RabbitMQ.
%%
%% The Initial Developer of the Original Code is VMware, Inc.
%% Copyright (c) 2007-2012 VMware, Inc. All rights reserved.
%%
-module(rabbit_top_wm_process).
-export([init/1, to_json/2, resource_exists/2, content_types_provided/2,
is_authorized/2]).
-define(PROCESS_INFO, [memory, message_queue_len, reductions, status]).
-include_lib("rabbitmq_management/include/rabbit_mgmt.hrl").
-include_lib("amqp_client/include/amqp_client.hrl").
-include_lib("webmachine/include/webmachine.hrl").
%%--------------------------------------------------------------------
init(_Config) -> {ok, #context{}}.
content_types_provided(ReqData, Context) ->
{[{"application/json", to_json}], ReqData, Context}.
to_json(ReqData, Context) ->
rabbit_mgmt_util:reply(process(ReqData), ReqData, Context).
resource_exists(ReqData, Context) ->
{case process(ReqData) of
not_found -> false;
_ -> true
end, ReqData, Context}.
is_authorized(ReqData, Context) ->
rabbit_mgmt_util:is_authorized_admin(ReqData, Context).
%%--------------------------------------------------------------------
process(ReqData) ->
PidBin = rabbit_mgmt_util:id(pid, ReqData),
try list_to_pid(binary_to_list(PidBin)) of
Pid -> [{pid, PidBin},
{name, rabbit_top_util:obtain_name(Pid)}] ++
case process_info(Pid, ?PROCESS_INFO) of
undefined -> [];
Props -> Props
end
catch
error:badarg ->
not_found
end.