From 5eba068e902ebd18f8368a783291292117a217fe Mon Sep 17 00:00:00 2001 From: Siraaj Khandkar Date: Sun, 13 Sep 2015 15:05:20 -0400 Subject: [PATCH] Collect processes stats. --- include/beam_stats.hrl | 2 +- include/beam_stats_process.hrl | 12 ++++++++ include/beam_stats_processes.hrl | 11 +++++++ src/beam_stats_process.erl | 53 ++++++++++++++++++++++++++++++++ src/beam_stats_processes.erl | 42 +++++++++++++++++++++++++ src/beam_stats_state.erl | 6 ++++ 6 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 include/beam_stats_process.hrl create mode 100644 include/beam_stats_processes.hrl create mode 100644 src/beam_stats_process.erl create mode 100644 src/beam_stats_processes.erl diff --git a/include/beam_stats.hrl b/include/beam_stats.hrl index 5624270..aaaf107 100644 --- a/include/beam_stats.hrl +++ b/include/beam_stats.hrl @@ -8,10 +8,10 @@ , reductions :: non_neg_integer() , run_queue :: non_neg_integer() , ets :: beam_stats_ets:t() + , processes :: beam_stats_processes:t() %, statistics :: [{atom() , term()}] %, system :: [{atom() , term()}] - %, process :: [{atom() , term()}] %, port :: [{atom() , term()}] %, dets :: [{atom() , term()}] }). diff --git a/include/beam_stats_process.hrl b/include/beam_stats_process.hrl new file mode 100644 index 0000000..65dc860 --- /dev/null +++ b/include/beam_stats_process.hrl @@ -0,0 +1,12 @@ +-record(beam_stats_process, + { pid :: pid() + , registered_name :: hope_option:t(atom()) + , raw_initial_call :: mfa() + , otp_initial_call :: hope_option:t(mfa()) + , otp_ancestors :: [{name, atom()} | {call, mfa()}] + , status :: beam_stats_process:status() + , memory :: non_neg_integer() + , total_heap_size :: non_neg_integer() + , stack_size :: non_neg_integer() + , message_queue_len :: non_neg_integer() + }). diff --git a/include/beam_stats_processes.hrl b/include/beam_stats_processes.hrl new file mode 100644 index 0000000..72cc30a --- /dev/null +++ b/include/beam_stats_processes.hrl @@ -0,0 +1,11 @@ +-record(beam_stats_processes, + { individual_stats = [] :: [beam_stats_process:t()] + , count_all = 0 :: non_neg_integer() + , count_exiting = 0 :: non_neg_integer() + , count_garbage_collecting = 0 :: non_neg_integer() + , count_registered = 0 :: non_neg_integer() + , count_runnable = 0 :: non_neg_integer() + , count_running = 0 :: non_neg_integer() + , count_suspended = 0 :: non_neg_integer() + , count_waiting = 0 :: non_neg_integer() + }). diff --git a/src/beam_stats_process.erl b/src/beam_stats_process.erl new file mode 100644 index 0000000..a06c48e --- /dev/null +++ b/src/beam_stats_process.erl @@ -0,0 +1,53 @@ +-module(beam_stats_process). + +-include("include/beam_stats_process.hrl"). + +-export_type( + [ t/0 + , status/0 + ]). + +-export( + [ of_pid/1 + ]). + +-type status() :: + exiting + | garbage_collecting + | runnable + | running + | suspended + | waiting + . + +-define(T, #?MODULE). + +-type t() :: + ?T{}. + +-spec of_pid(pid()) -> + t(). +of_pid(Pid) -> + Dict = pid_info_exn(Pid, dictionary), + ?T + { pid = Pid + , registered_name = pid_info_opt(Pid, registered_name) + , raw_initial_call = pid_info_exn(Pid, initial_call) + , otp_initial_call = hope_kv_list:get(Dict, '$initial_call') + , otp_ancestors = hope_kv_list:get(Dict, '$ancestors') + , status = pid_info_exn(Pid, status) + , memory = pid_info_exn(Pid, memory) + , total_heap_size = pid_info_exn(Pid, total_heap_size) + , stack_size = pid_info_exn(Pid, stack_size) + , message_queue_len = pid_info_exn(Pid, message_queue_len) + }. + +pid_info_exn(Pid, Key) -> + {some, Value} = pid_info_opt(Pid, Key), + Value. + +pid_info_opt(Pid, Key) -> + case {Key, erlang:process_info(Pid, Key)} + of {registered_name, []} -> none + ; {_ , {Key, Value}} -> {some, Value} + end. diff --git a/src/beam_stats_processes.erl b/src/beam_stats_processes.erl new file mode 100644 index 0000000..707a534 --- /dev/null +++ b/src/beam_stats_processes.erl @@ -0,0 +1,42 @@ +-module(beam_stats_processes). + +-include("include/beam_stats_process.hrl"). +-include("include/beam_stats_processes.hrl"). + +-export_type( + [ t/0 + ]). + +-export( + [ collect/0 + ]). + +-define(T, #?MODULE). + +-type t() :: + ?T{}. + +-spec collect() -> + t(). +collect() -> + Ps = [beam_stats_process:of_pid(P) || P <- erlang:processes()], + ?T + { individual_stats + = Ps + , count_all + = length(Ps) + , count_exiting + = length([P || P <- Ps, P#beam_stats_process.status =:= exiting]) + , count_garbage_collecting + = length([P || P <- Ps, P#beam_stats_process.status =:= garbage_collecting]) + , count_registered + = length(registered()) + , count_runnable + = length([P || P <- Ps, P#beam_stats_process.status =:= runnable]) + , count_running + = length([P || P <- Ps, P#beam_stats_process.status =:= running]) + , count_suspended + = length([P || P <- Ps, P#beam_stats_process.status =:= suspended]) + , count_waiting + = length([P || P <- Ps, P#beam_stats_process.status =:= waiting]) + }. diff --git a/src/beam_stats_state.erl b/src/beam_stats_state.erl index 7c41fc0..ad424d5 100644 --- a/src/beam_stats_state.erl +++ b/src/beam_stats_state.erl @@ -1,6 +1,8 @@ -module(beam_stats_state). -include("include/beam_stats.hrl"). +-include("include/beam_stats_process.hrl"). +-include("include/beam_stats_processes.hrl"). -export_type( [ t/0 @@ -14,6 +16,7 @@ -record(snapshots, { memory :: [{atom(), non_neg_integer()}] + , processes :: beam_stats_processes:t() , run_queue :: non_neg_integer() , ets :: beam_stats_ets:t() }). @@ -83,6 +86,7 @@ export( , snapshots = #snapshots { memory = Memory + , processes = Processes , run_queue = RunQueue , ets = ETS } @@ -114,11 +118,13 @@ export( , reductions = Reductions , run_queue = RunQueue , ets = ETS + , processes = Processes }. snapshots_new() -> #snapshots { memory = erlang:memory() + , processes = beam_stats_processes:collect() , run_queue = erlang:statistics(run_queue) , ets = beam_stats_ets:collect() }. -- 2.20.1