Current section
Files
Jump to
Current section
Files
src/dtopConsumer.erl
%%%-------------------------------------------------------------------
%%% File : dtopConsumer.erl
%%% Author : Mats Cronqvist <qthmacr@duna283>
%%% Created : 16 Dec 2003
%%% Description : rewrite of dtop for prf
%%%-------------------------------------------------------------------
-module(dtopConsumer).
-author('Mats Cronqvist').
-export(
[init/1
, terminate/1
, tick/2
, collectors/0
, config/2]).
-record(cld,
{fd=standard_io,
sort=cpu,
items=19}).
collectors() -> [prfPrc,prfSys].
init(_Node) -> #cld{}.
terminate(_LD) -> ok.
config(LD,{sort,S}) when S==cpu; S==mem; S==msgq -> LD#cld{sort=S};
config(LD,{fd,FD}) -> LD#cld{fd=FD};
config(LD,{items,Items}) -> LD#cld{items=Items};
config(LD,_) -> LD.
tick(LD,Data) ->
case Data of
[{prfPrc,PrfPrc},{prfSys,PrfSys}] -> print(LD,PrfSys,PrfPrc), LD;
_ -> LD
end.
print(#cld{fd=FD,sort=Sort,items=Items},PrfSys,PrfPrc) ->
print_del(FD),
print_sys(FD,PrfSys),
lwrite(FD,"~n",[]),
print_tags(FD),
print_procs(FD,Items,PrfSys,which_sort(Sort,PrfPrc)).
print_sys(FD,Sys) ->
lwrite(FD,"~s~n",[sys_str(Sys)]),
lwrite(FD,memf(),memi(Sys)).
memf() -> "memory: proc~8s, atom~8s, bin~8s, code~8s, ets~8s~n".
memi(Sys) ->
try [prf:human(lks(T,Sys)) || T <- [processes,atom,binary,code,ets]]
catch _:_ -> ["","","","",""]
end.
sys_str(Sys) ->
{_, Time} = calendar:now_to_local_time(lks(now, Sys)),
H = pad(element(1,Time),2,$0,left),
M = pad(element(2,Time),2,$0,left),
S = pad(element(3,Time),2,$0,left),
Node = to_list(lks(node, Sys)),
MEMbeam = prf:human(lks(beam_vss,Sys,0)),
MEM = prf:human(lks(total,Sys)),
CPUbeam = to_list(100*(lks(beam_user,Sys,0)+lks(beam_kernel,Sys,0))),
CPU = to_list(100*(lks(user,Sys,0)+lks(kernel,Sys,0))),
Procs = prf:human(lks(procs,Sys)),
RunQ = prf:human(lks(run_queue, Sys)),
SYS = lists:sublist(lists:append(["size: " ,MEM,
"(" ,MEMbeam,
"), cpu%: " ,CPUbeam,
"(" ,CPU,
"), procs: ",Procs,
", runq: " ,RunQ,
", ",H,":",M,":",S]),79),
pad(Node,79-length(SYS),$ , right)++SYS.
pad(Item,Len,Pad,LeftRight) ->
I = to_list(Item),
case length(I) of
L when L=:=Len -> I;
L when L<Len -> case LeftRight of
left -> lists:duplicate(Len-L,Pad)++I;
right-> I++lists:duplicate(Len-L,Pad)
end;
_ -> lists:sublist(I,Len)
end.
print_del(FD) ->
lwrite(FD,"~s~n", [lists:duplicate(79, $-)]).
format() -> "~-14s ~-28s ~-17s~7s~7s~4s~n".
tags() -> ["pid","name","current","msgq","mem","cpu"].
print_tags(FD) ->
lwrite(FD,format(),tags()).
which_sort( cpu,PrfPrc) -> expand(lks(dreds,PrfPrc),lks(info,PrfPrc));
which_sort(msgq,PrfPrc) -> expand(lks( msgq,PrfPrc),lks(info,PrfPrc));
which_sort(dmem,PrfPrc) -> expand(lks( dmem,PrfPrc),lks(info,PrfPrc));
which_sort( mem,PrfPrc) -> expand(lks( mem,PrfPrc),lks(info,PrfPrc)).
expand(Pids,Infos) ->
lists:reverse([[{pid,Pid}|lks(Pid,Infos)] || Pid <- Pids]).
print_procs(FD,Items,PrfSys,Prcs) ->
CpuPerRed = cpu_per_red(PrfSys),
[procsI(FD,P,CpuPerRed) || P <- resize(Items,Prcs)].
resize(no_pad,Prcs) ->
Prcs;
resize(Items,Prcs) ->
case Items < length(Prcs) of
true -> lists:sublist(Prcs,Items);
false-> Prcs++lists:duplicate(Items-length(Prcs),[])
end.
cpu_per_red(Sys) ->
CPU =
case lks(beam_user,Sys,1)+lks(beam_kernel,Sys,0) of
0.0 -> 1;
C -> C
end,
case lks(reductions,Sys) of
0 -> 0;
Reds -> 100*CPU/Reds
end.
procsI(FD,PP,CpuPerRed) ->
try
lwrite(FD,
format(),
[pidf(to_list(lks(pid,PP))),
funf(reg(PP)),
funf(lks(current_function, PP)),
prf:human(lks(message_queue_len, PP)),
prf:human(lks(memory,PP)),
to_list(lks(dreductions,PP)*CpuPerRed)])
catch _:_ ->
lwrite(FD,"~n",[])
end.
reg(PP) ->
case lks(registered_name, PP) of
[] -> lks(initial_call, PP);
Val -> Val
end.
pidf(Pid) ->
[_,A,B] = string:tokens(Pid,"."),
lists:append(["<0.",A,".",B]).
funf({M, F, A}) -> to_list(M)++":"++to_list(F)++"/"++to_list(A);
funf(Term) -> io_lib:fwrite("~p", [Term]).
to_list(A) when is_list(A) -> A;
to_list(A) when is_pid(A) -> pid_to_list(A);
to_list(A) when is_atom(A) -> atom_to_list(A);
to_list(A) when is_float(A) -> to_list(round(A));
to_list(A) when is_tuple(A) -> tuple_to_list(A);
to_list(A) when is_integer(A) -> integer_to_list(A).
lks(Tag,TVs,Def) ->
try lks(Tag,TVs)
catch {not_found, _} -> Def
end.
lks(Tag, []) -> throw({not_found, Tag});
lks(Tag, [{Tag,Val}|_]) -> Val;
lks(Tag, [_|List]) -> lks(Tag, List).
lwrite({Tab,LineNo},Format,As) when is_atom(Tab) ->
L = ets:update_counter(Tab,LineNo,1),
ets:insert(Tab,{L,flat(Format,As)});
lwrite(FD,Format,As) ->
io:fwrite(FD,Format,As).
flat(F,A) ->
lists:flatten(io_lib:fwrite(F,A)).