%%%------------------------------------------------------------------- %%% File : dtopConsumer.erl %%% Author : Mats Cronqvist %%% 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 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)).