From 3ee9ff01e3b9bc3aefa057a554bf443a6c026191 Mon Sep 17 00:00:00 2001 From: zhongwencool Date: Fri, 27 Aug 2021 09:21:11 +0800 Subject: [PATCH 1/3] application included started/starting/loaded/loading status --- include/observer_cli.hrl | 2 +- src/observer_cli_application.erl | 174 ++++++++++++++++++------------- 2 files changed, 103 insertions(+), 73 deletions(-) diff --git a/include/observer_cli.hrl b/include/observer_cli.hrl index 5e45136..fbb8917 100644 --- a/include/observer_cli.hrl +++ b/include/observer_cli.hrl @@ -17,7 +17,7 @@ }). -record(app, { - type = {memory, 1} :: {atom(), pos_integer()}, + type = {proc_count, 1} :: {atom(), pos_integer()}, cur_page = 1 :: pos_integer(), interval = ?DEFAULT_INTERVAL :: pos_integer() }). diff --git a/src/observer_cli_application.erl b/src/observer_cli_application.erl index dd119cf..1e3fc6c 100644 --- a/src/observer_cli_application.erl +++ b/src/observer_cli_application.erl @@ -34,18 +34,18 @@ manager(Pid, Opts = #view_opts{app = App = #app{cur_page = CurPage}}) -> erlang:unlink(Pid), erlang:send(Pid, quit), quit; + {func, proc_count, message_queue_len} -> + clean([Pid]), + start(Opts#view_opts{app = App#app{type = {message_queue_len, 4}}}); {func, proc_count, reductions} -> clean([Pid]), - start(Opts#view_opts{app = App#app{type = {reductions, 2}}}); + start(Opts#view_opts{app = App#app{type = {reductions, 3}}}); {func, proc_count, memory} -> clean([Pid]), - start(Opts#view_opts{app = App#app{type = {memory, 3}}}); - {func, proc_count, message_queue_len} -> - clean([Pid]), - start(Opts#view_opts{app = App#app{type = {message_queue_len, 4}}}); + start(Opts#view_opts{app = App#app{type = {memory, 2}}}); pause_or_resume -> clean([Pid]), - start(Opts#view_opts{app = App#app{type = {process_count, 5}}}); + start(Opts#view_opts{app = App#app{type = {proc_count, 1}}}); {new_interval, NewInterval} -> clean([Pid]), start(Opts#view_opts{app = App#app{interval = NewInterval}}); @@ -80,14 +80,14 @@ render_worker(App, AutoRow) -> render_app_info(Row, CurPage, {Type, N}) -> List = [ begin - {0, element(N, I), [App, C, R, M, Q, V, S]} + {0, {element(N, I), S}, [App, C, M, R, Q, S, V]} end - || {{App, V}, I = {S, R, M, Q, C}} <- maps:to_list(app_info()) + || {App, I = {C, M, R, Q, S, V}} <- maps:to_list(app_info()) ], {StartPos, SortList} = observer_cli_lib:sublist(List, Row, CurPage), InitColor = [ {memory, ?GRAY_BG}, - {process_count, ?GRAY_BG}, + {proc_count, ?GRAY_BG}, {reductions, ?GRAY_BG}, {message_queue_len, ?GRAY_BG} ], @@ -117,7 +117,7 @@ render_app_info(Row, CurPage, {Type, N}) -> ]), {_, View} = lists:foldl( fun({_, _, Item}, {Pos, Acc}) -> - [App, C, R, M, Q, V, S] = Item, + [App, C, R, M, Q, S, V] = Item, {Pos + 1, [ ?render([ ?W(Pos, 2), @@ -137,76 +137,106 @@ render_app_info(Row, CurPage, {Type, N}) -> ), [Title | lists:reverse(View)]. --define(Unknown, {unknown, unknown}). - app_info() -> Info = application:info(), + AllApps = app_status(Info), + Leaders = leader_info(Info), + app_info(AllApps, Leaders, erlang:processes(), self()). + +app_info(AllApps, _Leaders, [], _Self) -> + AllApps; +app_info(AllApps, Leaders, [Self | Process], Self) -> + app_info(AllApps, Leaders, Process, Self); +app_info(AllApps, Leaders, [Pid | Process], Self) -> + case erlang:process_info(Pid, [group_leader, memory, reductions, message_queue_len]) of + undefined -> + app_info(AllApps, Leaders, Process, Self); + Prop -> + [ + {group_leader, Group}, + {memory, Memory}, + {reductions, Reds}, + {message_queue_len, MsgQ} + ] = Prop, + NewAllApps = + case maps:find(Group, Leaders) of + error -> + {ok, {C1, M1, R1, Q1, S1, V1}} = maps:find(unknown, AllApps), + NewInfo = {C1 + 1, M1 + Memory, R1 + Reds, Q1 + MsgQ, S1, V1}, + maps:put(unknown, NewInfo, AllApps); + {ok, App} -> + {ok, {C, M, R, Q, S, V}} = maps:find(App, AllApps), + maps:put(App, {C + 1, M + Memory, R + Reds, Q + MsgQ, S, V}, AllApps) + end, + app_info(NewAllApps, Leaders, Process, Self) + end. + +leader_info(Info) -> {running, Running} = lists:keyfind(running, 1, Info), + leader_info(Running, #{}). + +leader_info([{App, Sup} | Running], Acc) when is_pid(Sup) -> + NewAcc = + case erlang:process_info(Sup, group_leader) of + undefined -> + Acc; + {group_leader, Pid} -> + Acc#{Pid => App} + end, + leader_info(Running, NewAcc); +leader_info([_ | Running], Acc) -> + leader_info(Running, Acc); +leader_info([], Acc) -> + Acc. + +app_status(Info) -> {loaded, Loaded} = lists:keyfind(loaded, 1, Info), {loading, Loading} = lists:keyfind(loading, 1, Info), {started, Started} = lists:keyfind(started, 1, Info), {start_p_false, StartPFalse} = lists:keyfind(start_p_false, 1, Info), {starting, Starting} = lists:keyfind(starting, 1, Info), - Leaders = - lists:foldl( - fun - ({_App, undefined}, Acc) -> - Acc; - ({App, Sup}, Acc) -> - case erlang:process_info(Sup, group_leader) of - undefined -> - Acc; - {group_leader, Pid} -> - {_, _, Version} = lists:keyfind(App, 1, Loaded), - Acc#{Pid => {App, Version}} - end - end, - #{}, - Running - ), - Status = lists:foldl(fun({App, _desc, Version}, Acc) -> - IsLoading = lists:keyfind(App, 1, Loading) =/= false, - IsStarting = lists:keyfind(App, 1, Starting) =/= false, - IsStartPFalse = lists:keyfind(App, 1, StartPFalse) =/= false, - IsStarted = lists:keyfind(App, 1, Started) =/= false, - IsLoaded = lists:keyfind(App, 1, Loaded) =/= false, - case {IsLoading, IsStarting, IsStartPFalse, IsStarted, IsLoaded} of - {true, _, _, _, _} -> Acc#{{App, Version} => "Loading"}; - {_, true, _, _, _} -> Acc#{{App, Version} => "Starting"}; - {_, _, true, _, _} -> Acc#{{App, Version} => "StartPFalse"}; - {_, _, _, true, _} -> Acc#{{App, Version} => "Started"}; - {_, _, _, _, true} -> Acc#{{App, Version} => "Loaded"}; - _ -> Acc#{{App, Version} => "Unknown"} - end - end, #{}, application:which_applications(5000)), + R0 = #{unknown => {0, 0, 0, 0, "Unknown", "unknown"}}, + R1 = lists:foldl( + fun({App, _From}, Acc) -> + Acc#{App => {0, 0, 0, 0, "Loading", "unknown"}} + end, + R0, + Loading + ), + R2 = lists:foldl( + fun({App, _Desc, Version}, Acc) -> + Acc#{App => {0, 0, 0, 0, "Loaded", Version}} + end, + R1, + Loaded + ), + R3 = lists:foldl( + fun({App, _RestartType, _Type, _From}, Acc) -> + Version = get_version(App, Acc), + Acc#{App => {0, 0, 0, 0, "Starting", Version}} + end, + R2, + Starting + ), + R4 = lists:foldl( + fun({App, _RestartType}, Acc) -> + Version = get_version(App, Acc), + Acc#{App => {0, 0, 0, 0, "Started", Version}} + end, + R3, + Started + ), lists:foldl( - fun(Pid, Acc) -> - case erlang:process_info(Pid, [group_leader, memory, reductions, message_queue_len]) of - undefined -> - Acc; - Prop -> - [ - {group_leader, Group}, - {memory, Memory}, - {reductions, Reds}, - {message_queue_len, MsgQ} - ] = Prop, - case maps:find(Group, Leaders) of - error -> - {ok, {S1, R1, M1, Q1, C1}} = maps:find(?Unknown, Acc), - NewInfo = {S1, R1 + Reds, M1 + Memory, Q1 + MsgQ, C1 + 1}, - maps:put(?Unknown, NewInfo, Acc); - {ok, AppInfo} -> - case maps:find(AppInfo, Acc) of - {ok, {S, R, M, Q, C}} -> - maps:put(AppInfo, {S, R + Reds, M + Memory, Q + MsgQ, C + 1}, Acc); - error -> - {ok, S} = maps:find(AppInfo, Status), - maps:put(AppInfo, {S, Reds, Memory, MsgQ, 1}, Acc) - end - end - end + fun({App, _RestartType, _Type, _From}, Acc) -> + Version = get_version(App, Acc), + Acc#{App => {0, 0, 0, 0, "StartPFlase", Version}} end, - #{?Unknown => {"unknown", 0, 0, 0, 0}}, - erlang:processes() + R4, + StartPFalse ). + +get_version(App, Maps) -> + case maps:find(App, Maps) of + {ok, {_, _, _, _, _, V}} -> V; + _ -> "unknown" + end. From 17a46017572d5bf60859a1e11c40474d8044841a Mon Sep 17 00:00:00 2001 From: zhongwencool Date: Fri, 27 Aug 2021 09:36:05 +0800 Subject: [PATCH 2/3] fixed: ctrl+c to break will get bagarg when staring observer_cli by rpc [{erlang,'--',[{error,terminated},"\n"],[]},{observer_cli_lib,parse_integer,1,[{file,"observer_cli_lib.erl"},{line,387}]},{observer_cli,manager,4,[{file,"observer_cli.erl"},{line,101}]},{emqx_ctl,run_command,2,[{file,"emqx_ctl.erl"},{line,104}]},{erpc,execute_call,4,[{file,"erpc.erl"},{line,416}]}] --- src/observer_cli_lib.erl | 3 +++ src/observer_cli_plugin.erl | 2 ++ src/observer_cli_process.erl | 3 +++ 3 files changed, 8 insertions(+) diff --git a/src/observer_cli_lib.erl b/src/observer_cli_lib.erl index d485ae1..368e4a1 100644 --- a/src/observer_cli_lib.erl +++ b/src/observer_cli_lib.erl @@ -362,6 +362,9 @@ parse_cmd(ViewOpts, Module, Args) -> hide; "`\n" -> scheduler_usage; + %% {error, estale}|{error, terminated} + {error, _Reason} -> + quit; Number -> parse_integer(Number) end. diff --git a/src/observer_cli_plugin.erl b/src/observer_cli_plugin.erl index 7d88d1d..19b4b15 100644 --- a/src/observer_cli_plugin.erl +++ b/src/observer_cli_plugin.erl @@ -230,6 +230,8 @@ parse_cmd() -> "F\n" -> page_down_top_n; "q\n" -> quit; "\n" -> jump; + %% {error, estale}|{error, terminated} + {error, _Reason} -> quit; Number -> observer_cli_lib:parse_integer(Number) end. diff --git a/src/observer_cli_process.erl b/src/observer_cli_process.erl index 56dbf91..aaf19a2 100644 --- a/src/observer_cli_process.erl +++ b/src/observer_cli_process.erl @@ -426,6 +426,9 @@ parse_cmd() -> home; "B\n" -> back; + %% {error, estale}|{error, terminated} + {error, _Reason} -> + quit; Number -> observer_cli_lib:parse_integer(Number) end. From 3b440a048bef2c8aff2cdbe29b622f975c89d1b7 Mon Sep 17 00:00:00 2001 From: zhongwencool Date: Fri, 27 Aug 2021 09:43:35 +0800 Subject: [PATCH 3/3] bump 1.7.1 --- README.md | 6 +++++- mix.exs | 2 +- src/observer_cli.app.src | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a006a72..e8de4f2 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Visualize Erlang/Elixir Nodes On The Command Line base on [recon](https://github %% rebar.config {deps, [observer_cli]} %% erlang.mk -dep_observer_cli = hex 1.7.0 +dep_observer_cli = hex 1.7.1 ``` **Elixir** ```elixir @@ -223,6 +223,10 @@ Support F/B to page up/down. ---------------- ### Changelog +- 1.7.1 + - application view show starting/loading/startPfalse/loaded/started application. + - fixed badarg when staring by rpc and stop by `ctrl+c`. + - fixed mix.exe version error - 1.7.0 - application view support reductions/memory/process_count sort - plugin support `{byte, 1024}` to `10.0000 KB` diff --git a/mix.exs b/mix.exs index fe41c1e..7320fba 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule ObserverCli.MixProject do def project do [ app: :observer_cli, - version: "1.6.2", + version: "1.7.1", language: :erlang, description: "observer in shell", deps: [ diff --git a/src/observer_cli.app.src b/src/observer_cli.app.src index 815ef30..c9727ad 100644 --- a/src/observer_cli.app.src +++ b/src/observer_cli.app.src @@ -1,7 +1,7 @@ {application, observer_cli, [ {description, "Visualize Erlang Nodes On The Command Line"}, - {vsn, "1.7.0"}, + {vsn, "1.7.1"}, {modules, [ observer_cli ]},