Permalink
Browse files

Add "riak-admin top" subcommand

Usage: riak-admin top [-interval N] \
                      [-sort reductions|memory|msg_q} \
                      [-lines N]

Also, added a new directory to the packaging, lib/basho-patches,
for patched .beam files.  The packaging changes compile and copy
a modified etop_txt.beam file into this new dir.

NOTE: This new lib/basho-patches directory is added to the code
server's path with the "-pa" flag, so it can be used to patch
any non-sticky BEAM file.

Edits to src/etop_txt.erl change the column widths for several
columns to be more useful to humans: since the output is wider
than 80 colums, we make the new output just shy of 132 columns.
  • Loading branch information...
1 parent b625533 commit 3f74e8a79d42708e41852e7cd9fb9a17102b7e66 Scott Lystig Fritchie committed Jan 4, 2012
Showing with 168 additions and 2 deletions.
  1. +3 −0 ebin/riak.app
  2. +2 −0 rel/files/riak
  3. +25 −1 rel/files/riak-admin
  4. +3 −1 rel/reltool.config
  5. +135 −0 src/etop_txt.erl
View
@@ -0,0 +1,3 @@
+{application,riak,
+ [{description,"Riak extremely-early boot items"},
+ {modules,[etop_txt]}]}.
View
@@ -7,6 +7,7 @@ RUNNER_SCRIPT=${0##*/}
RUNNER_BASE_DIR={{runner_base_dir}}
RUNNER_ETC_DIR={{runner_etc_dir}}
+RUNNER_LIB_DIR={{platform_lib_dir}}
RUNNER_LOG_DIR={{runner_log_dir}}
PIPE_DIR={{pipe_dir}}
RUNNER_USER={{runner_user}}
@@ -227,6 +228,7 @@ case "$1" in
PROGNAME=`echo $0 | sed 's/.*\///'`
CMD="$BINDIR/erlexec -boot $RUNNER_BASE_DIR/releases/$APP_VSN/$SCRIPT \
-embedded -config $RUNNER_ETC_DIR/app.config \
+ -pa $RUNNER_LIB_DIR/basho-patches \
-args_file $RUNNER_ETC_DIR/vm.args -- ${1+"$@"}"
export EMU
export ROOTDIR
View
@@ -5,6 +5,7 @@ RUNNER_SCRIPT=${0##*/}
RUNNER_BASE_DIR={{runner_base_dir}}
RUNNER_ETC_DIR={{runner_etc_dir}}
+RUNNER_LIB_DIR={{platform_lib_dir}}
RUNNER_LOG_DIR={{runner_log_dir}}
RUNNER_USER={{runner_user}}
@@ -326,6 +327,7 @@ case "$1" in
OLDNODE=$1
NEWNODE=$2
$ERTS_PATH/erl -noshell \
+ -pa $RUNNER_LIB_DIR/basho-patches \
-config $RUNNER_ETC_DIR/app.config \
-eval "riak_kv_console:$ACTION(['$OLDNODE', '$NEWNODE'])" \
-s init stop
@@ -345,6 +347,7 @@ case "$1" in
FILENAME=$3
$ERTS_PATH/erl -noshell $NAME_PARAM riak_kv_backup$NAME_HOST -setcookie $COOKIE \
+ -pa $RUNNER_LIB_DIR/basho-patches \
-eval "riak_kv_backup:$ACTION('$NODE', \"$FILENAME\")" -s init stop
;;
@@ -363,6 +366,7 @@ case "$1" in
TYPE=$4
$ERTS_PATH/erl -noshell $NAME_PARAM riak_kv_backup$NAME_HOST -setcookie $COOKIE \
+ -pa $RUNNER_LIB_DIR/basho-patches \
-eval "riak_kv_backup:$ACTION('$NODE', \"$FILENAME\", \"$TYPE\")" -s init stop
;;
@@ -380,17 +384,37 @@ case "$1" in
NODE_NAME=${NAME_ARG#* }
$ERTS_PATH/erl -noshell $NAME_PARAM riak_test$NAME_HOST $COOKIE_ARG \
+ -pa $RUNNER_LIB_DIR/basho-patches \
-eval "case catch(riak:client_test(\"$NODE_NAME\")) of \
ok -> init:stop(); \
_ -> init:stop(1) \
end."
;;
+ top)
+ # Make sure the local node IS running
+ RES=`$NODETOOL ping`
+ if [ "$RES" != "pong" ]; then
+ echo "Node is not running!"
+ exit 1
+ fi
+ shift
+
+ MYPID=$$
+ NODE_NAME=${NAME_ARG#* }
+ $ERTS_PATH/erl -noshell -noinput \
+ -pa $RUNNER_LIB_DIR/basho-patches \
+ -hidden $NAME_PARAM riak_etop$MYPID$NAME_HOST $COOKIE_ARG \
+ -s etop -s erlang halt -output text \
+ -node $NODE_NAME \
+ $* -tracing off
+ ;;
*)
echo "Usage: $SCRIPT { join | leave | backup | restore | test | status | "
echo " reip | js_reload | wait-for-service | ringready | "
echo " transfers | force-remove | down | cluster_info | "
- echo " member_status | ring_status | vnode-status}"
+ echo " member_status | ring_status | vnode-status} |"
+ echo " top [-interval N] [-sort reductions|memory|msg_q} [-lines N]"
exit 1
;;
esac
View
@@ -70,7 +70,9 @@
{template, "files/riak", "bin/riak"},
{template, "files/riak-admin", "bin/riak-admin"},
{template, "files/search-cmd", "bin/search-cmd"},
- {template, "files/vm.args", "etc/vm.args"}
+ {template, "files/vm.args", "etc/vm.args"},
+ {mkdir, "lib/basho-patches"},
+ {copy, "../ebin/etop_txt.beam", "lib/basho-patches"}
]}.
View
@@ -0,0 +1,135 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% 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.
+%%
+%% %CopyrightEnd%
+%%
+-module(etop_txt).
+-author('siri@erix.ericsson.se').
+-author('scott@basho.com').
+
+%%-compile(export_all).
+-export([init/1,stop/1]).
+-export([do_update/3]).
+
+%%-include("etop.hrl").
+-record(etop_proc_info,
+ {pid,
+ mem=0,
+ reds=0,
+ name,
+ runtime=0,
+ cf,
+ mq=0}).
+-record(etop_info,
+ {now = {0, 0, 0},
+ n_procs = 0,
+ wall_clock = {0, 0},
+ runtime = {0, 0},
+ run_queue = 0,
+ alloc_areas = [],
+ memi = [{total, 0},
+ {processes, 0},
+ {ets, 0},
+ {atom, 0},
+ {code, 0},
+ {binary, 0}],
+ procinfo = []
+ }).
+%%-include("etop_defs.hrl").
+-define(SYSFORM,
+ " ~-72w~10s~n"
+ " Load: cpu ~8w Memory: total ~8w binary ~8w~n"
+ " procs~8w processes~8w code ~8w~n"
+ " runq ~8w atom ~8w ets ~8w~n").
+-record(opts, {node=node(), port = 8415, accum = false, intv = 5000, lines = 10,
+ width = 700, height = 340, sort = runtime, tracing = on,
+ %% Other state information
+ out_mod=etop_gui, out_proc, server, host, tracer, store,
+ accum_tab, remote}).
+
+-import(etop,[loadinfo/1,meminfo/2]).
+-import(etop_gui,[formatmfa/1,to_list/1]).
+
+-define(PROCFORM,"~-20w~-25s~8w~11w~11w~11w ~-40s~n").
+
+stop(Pid) -> Pid ! stop.
+
+init(Config) ->
+ loop(Config).
+
+loop(Config) ->
+ Info = do_update(Config),
+ receive
+ stop -> stopped;
+ {dump,Fd} -> do_update(Fd,Info,Config), loop(Config);
+ {config,_,Config1} -> loop(Config1)
+ after Config#opts.intv-500 -> loop(Config)
+ end.
+
+do_update(Config) ->
+ Info = etop:update(Config),
+ do_update(standard_io,Info,Config).
+
+do_update(Fd,Info,Config) ->
+ {Cpu,NProcs,RQ,Clock} = loadinfo(Info),
+ io:nl(Fd),
+ writedoubleline(Fd),
+ case Info#etop_info.memi of
+ undefined ->
+ io:fwrite(Fd, " ~-72w~10s~n"
+ " Load: cpu ~8w~n"
+ " procs~8w~n"
+ " runq ~8w~n",
+ [Config#opts.node,Clock,
+ Cpu,NProcs,RQ]);
+ Memi ->
+ [Tot,Procs,Atom,Bin,Code,Ets] =
+ meminfo(Memi, [total,processes,atom,binary,code,ets]),
+ io:fwrite(Fd, ?SYSFORM,
+ [Config#opts.node,Clock,
+ Cpu,Tot,Bin,
+ NProcs,Procs,Code,
+ RQ,Atom,Ets])
+ end,
+ io:nl(Fd),
+ writepinfo_header(Fd),
+ writesingleline(Fd),
+ writepinfo(Fd,Info#etop_info.procinfo),
+ %%writedoubleline(Fd),
+ %%io:nl(Fd),
+ Info.
+
+writepinfo_header(Fd) ->
+ io:fwrite(Fd,"Pid Name or Initial Func Time Reds Memory MsgQ Current Function~n",[]).
+
+writesingleline(Fd) ->
+ io:fwrite(Fd,"-------------------------------------------------------------------------------------------------------------------------------~n",[]).
+writedoubleline(Fd) ->
+ io:fwrite(Fd,"===============================================================================================================================~n",[]).
+
+writepinfo(Fd,[#etop_proc_info{pid=Pid,
+ mem=Mem,
+ reds=Reds,
+ name=Name,
+ runtime=Time,
+ cf=MFA,
+ mq=MQ}
+ |T]) ->
+ io:fwrite(Fd,?PROCFORM,[Pid,to_list(Name),Time,Reds,Mem,MQ,formatmfa(MFA)]),
+ writepinfo(Fd,T);
+writepinfo(_Fd,[]) ->
+ ok.
+

0 comments on commit 3f74e8a

Please sign in to comment.