From b85051633ee2b5132b058b9187762ddaa958a3b2 Mon Sep 17 00:00:00 2001 From: William Schroeder Date: Wed, 29 Dec 2021 11:36:12 -0600 Subject: [PATCH 1/2] Some applications do not start supervisor children (CRITICAL) This code filters out children that are not supervisors so we can avoid crashing remote processes that do not handle the which_children message. I marked this as critical, as monitoring should not crash remote systems. --- apps/epl_st/src/epl_st.erl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/epl_st/src/epl_st.erl b/apps/epl_st/src/epl_st.erl index 53fa81b..51afd1c 100644 --- a/apps/epl_st/src/epl_st.erl +++ b/apps/epl_st/src/epl_st.erl @@ -92,6 +92,9 @@ code_change(_OldVsn, State, _Extra) -> %%% Internal functions %%%=================================================================== +is_supervisor(Pid) -> + element(1, proc_lib:initial_call(Pid)) == supervisor. + generate_sup_tree({_Name, Pid, worker, _Mods}) -> worker_node(Pid); generate_sup_tree({_Name, Pid, supervisor, _Mods}) -> @@ -101,7 +104,11 @@ generate_sup_tree(undefined) -> #{}; generate_sup_tree(MasterPid) -> {SupPid, _SupName} = command(fun application_master:get_child/1, [MasterPid]), - Children = command(fun supervisor:which_children/1, [SupPid]), + IsSupervisor = is_supervisor(SupPid), + Children = if + IsSupervisor -> command(fun supervisor:which_children/1, [SupPid]); + true -> [] + end, sup_node(SupPid, generate_children(Children)). generate_children(Children) -> From 719cbd481dd7d64fee47756949491d5f67ae661a Mon Sep 17 00:00:00 2001 From: William Schroeder Date: Wed, 29 Dec 2021 11:39:01 -0600 Subject: [PATCH 2/2] More safely handle race condition of ETS tables vanishing mid-query The time between ets:all/0 and the series of ets:info/1 is enough time for tables that exist in ets:all/0's output to vanish in systems with temporary process trees. This code filters out the caught crashes due to the tables not existing. --- apps/epl_ets/src/epl_ets_metric.erl | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/epl_ets/src/epl_ets_metric.erl b/apps/epl_ets/src/epl_ets_metric.erl index 41eadab..53b6bce 100644 --- a/apps/epl_ets/src/epl_ets_metric.erl +++ b/apps/epl_ets/src/epl_ets_metric.erl @@ -96,8 +96,11 @@ calculate_memory_percent(MemoryData) -> get_ets_info(Node, Tab) -> {ok, Info} = epl:command(Node, fun ets:info/1, [Tab]), - InfoMap = proplist_to_map(Info), - {Tab, InfoMap}. + if + Info == undefined -> {Tab, #{}}; + true -> InfoMap = proplist_to_map(Info), + {Tab, InfoMap} + end. transform_traces_by_pid(Traces) -> TracesByPid = split_traces_by_pid(Traces), @@ -211,6 +214,9 @@ namify_val(Val) -> namify(Name) -> epl_viz_map:namify(Name). + +proplist_to_map({'EXIT', _reason}) -> #{}; + proplist_to_map(Proplist) -> lists:foldl(fun({Prop, Val}, Map) -> maps:put(namify(Prop), namify_val(Val), Map) end, #{}, Proplist).