From ffcacd111c61019a502a895b1edcfbc1578ddfa7 Mon Sep 17 00:00:00 2001 From: Dan Gudmundsson Date: Mon, 3 Oct 2011 14:12:32 +0200 Subject: [observer] Clean up code system tab, timer handling and "etop" code More info in system tab, same timer handling in all tabs. Remove dependency off etop process, do the roughly the same functionality on our own. --- lib/observer/src/observer_sys_wx.erl | 324 ++++++++++++++--------------------- 1 file changed, 126 insertions(+), 198 deletions(-) (limited to 'lib/observer/src/observer_sys_wx.erl') diff --git a/lib/observer/src/observer_sys_wx.erl b/lib/observer/src/observer_sys_wx.erl index 5116891e91..5bc5fd49f6 100644 --- a/lib/observer/src/observer_sys_wx.erl +++ b/lib/observer/src/observer_sys_wx.erl @@ -24,6 +24,8 @@ -export([init/1, handle_info/2, terminate/2, code_change/3, handle_call/3, handle_event/2, handle_cast/2]). +-export([sys_info/0]). + -include_lib("wx/include/wx.hrl"). -include("observer_defs.hrl"). @@ -33,172 +35,102 @@ %% Records -record(sys_wx_state, {parent, - panel, - menubar, - parent_notebook, - no_procs, - no_cpu, - no_cpu_available, - no_cpu_online, - tot_alloc, - proc_used, - proc_alloc, - atom_used, - atom_alloc, - binary_alloc, - code_alloc, - ets_alloc, - node_label, node, - refr_timer = false, - refr_intv = 30}). + parent_notebook, + panel, sizer, + menubar, + fields, + timer}). start_link(Notebook, Parent) -> wx_object:start_link(?MODULE, [Notebook, Parent], []). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -init([Notebook, Parent]) -> - SysPanel = wxPanel:new(Notebook, []), - - %% Setup sizers - SysSizer = wxBoxSizer:new(?wxVERTICAL), - - SysNodeSizer = wxStaticBoxSizer:new(?wxHORIZONTAL, SysPanel, [{label, "Node:"}]), - - SysLoadSizer = wxStaticBoxSizer:new(?wxHORIZONTAL, SysPanel, [{label, "Load:"}]), - SysLeftLoadSizer = wxBoxSizer:new(?wxVERTICAL), - SysMidLoadSizer = wxBoxSizer:new(?wxHORIZONTAL), - SysRightLoadSizer = wxBoxSizer:new(?wxVERTICAL), - - SysMemSizer = wxStaticBoxSizer:new(?wxHORIZONTAL, SysPanel, [{label, "Memory:"}]), - SysLeftMemSizer = wxBoxSizer:new(?wxVERTICAL), - SysMidMemSizer = wxBoxSizer:new(?wxHORIZONTAL), - SysRightMemSizer = wxBoxSizer:new(?wxVERTICAL), - - wxSizer:add(SysSizer, SysNodeSizer, [{flag, ?wxEXPAND}]), - wxSizer:add(SysSizer, SysLoadSizer, [{flag, ?wxEXPAND}]), - wxSizer:add(SysSizer, SysMemSizer, [{flag, ?wxEXPAND}]), - wxSizer:add(SysLoadSizer, SysLeftLoadSizer), - wxSizer:add(SysLoadSizer, SysMidLoadSizer), - wxSizer:add(SysLoadSizer, SysRightLoadSizer), - - wxSizer:add(SysMemSizer, SysLeftMemSizer), - wxSizer:add(SysMemSizer, SysMidMemSizer), - wxSizer:add(SysMemSizer, SysRightMemSizer), - - wxSizer:addSpacer(SysMidLoadSizer, 90), - wxSizer:addSpacer(SysMidMemSizer, 70), - - %% Create labels - NodeInfo = get_syspage_info(node()), - NodeLabel = create_info_label(SysPanel, SysNodeSizer, observer_sys:node_name_str(NodeInfo)), - - create_info_label(SysPanel, SysLeftLoadSizer, "logical CPU's:"), - create_info_label(SysPanel, SysLeftLoadSizer, "logical CPU's available:"), - create_info_label(SysPanel, SysLeftLoadSizer, "logical CPU's online:"), - create_info_label(SysPanel, SysLeftLoadSizer, "existing processes:"), - NoCpuTxt = create_info_label(SysPanel, SysRightLoadSizer, observer_sys:no_cpu_str(NodeInfo)), - NoCpuAvTxt = create_info_label(SysPanel, SysRightLoadSizer, observer_sys:no_cpu_available_str(NodeInfo)), - NoCpuOnTxt = create_info_label(SysPanel, SysRightLoadSizer, observer_sys:no_cpu_online_str(NodeInfo)), - NoProcsTxt = create_info_label(SysPanel, SysRightLoadSizer, observer_sys:no_procs_str(NodeInfo)), - - create_info_label(SysPanel, SysLeftMemSizer, "total allocated:"), - create_info_label(SysPanel, SysLeftMemSizer, "used by processes:"), - create_info_label(SysPanel, SysLeftMemSizer, "allocated for processes:"), - create_info_label(SysPanel, SysLeftMemSizer, "used by atoms:"), - create_info_label(SysPanel, SysLeftMemSizer, "allocated for atoms:"), - create_info_label(SysPanel, SysLeftMemSizer, "allocated for binaries:"), - create_info_label(SysPanel, SysLeftMemSizer, "allocated for code"), - create_info_label(SysPanel, SysLeftMemSizer, "allocated for ETS:"), - TotAllocTxt = create_info_label(SysPanel, SysRightMemSizer, observer_sys:tot_alloc_str(NodeInfo)), - ProcUsedTxt = create_info_label(SysPanel, SysRightMemSizer, observer_sys:proc_used_str(NodeInfo)), - ProcAllocTxt = create_info_label(SysPanel, SysRightMemSizer, observer_sys:proc_alloc_str(NodeInfo)), - AtomUsedTxt = create_info_label(SysPanel, SysRightMemSizer, observer_sys:atom_used_str(NodeInfo)), - AtomAllocTxt = create_info_label(SysPanel, SysRightMemSizer, observer_sys:atom_alloc_str(NodeInfo)), - BinaryAllocTxt = create_info_label(SysPanel, SysRightMemSizer, observer_sys:binary_alloc_str(NodeInfo)), - CodeAllocTxt = create_info_label(SysPanel, SysRightMemSizer, observer_sys:code_alloc_str(NodeInfo)), - EtsAllocTxt = create_info_label(SysPanel, SysRightMemSizer, observer_sys:ets_alloc_str(NodeInfo)), - - %% Create StateRecord - SysPanelState = #sys_wx_state{ - parent = Parent, - panel = SysPanel, - parent_notebook = Notebook, - node_label = NodeLabel, - no_procs = NoProcsTxt, - no_cpu = NoCpuTxt, - no_cpu_available = NoCpuAvTxt, - no_cpu_online= NoCpuOnTxt, - tot_alloc = TotAllocTxt, - proc_used = ProcUsedTxt, - proc_alloc = ProcAllocTxt, - atom_used = AtomUsedTxt, - atom_alloc = AtomAllocTxt, - binary_alloc = BinaryAllocTxt, - code_alloc = CodeAllocTxt, - ets_alloc = EtsAllocTxt, - node = node()}, - - wxPanel:setSizer(SysPanel, SysSizer), - {SysPanel, SysPanelState}. - -get_syspage_info(Node) -> - observer_wx:try_rpc(Node, observer_sys, node_info, []). - -create_info_label(Panel, Sizer, Msg) -> - WxText = wxStaticText:new(Panel, ?wxID_ANY, Msg), - wxSizer:add(Sizer, WxText), - WxText. +init(Args) -> + try + init2(Args) + catch E:R -> + io:format("~p:~p ~p~n",[E,R, erlang:get_stacktrace()]) + end. + +init2([Notebook, Parent]) -> + SysInfo = sys_info(), + {Info, Stat} = info_fields(), + Panel = wxPanel:new(Notebook), + Sizer = wxBoxSizer:new(?wxHORIZONTAL), + {FPanel0, _FSizer0, Fields0} = observer_lib:display_info(Panel, fill_info(Info, SysInfo)), + {FPanel1, _FSizer1, Fields1} = observer_lib:display_info(Panel, fill_info(Stat, SysInfo)), + wxSizer:add(Sizer, FPanel0, [{flag, ?wxEXPAND bor ?wxTOP bor ?wxBOTTOM bor ?wxLEFT}, + {proportion, 1}, {border, 5}]), + wxSizer:add(Sizer, FPanel1, [{flag, ?wxEXPAND bor ?wxTOP bor ?wxBOTTOM bor ?wxRIGHT}, + {proportion, 1}, {border, 5}]), + wxPanel:setSizer(Panel, Sizer), + Timer = observer_lib:start_timer(10), + {Panel, #sys_wx_state{parent=Parent, + parent_notebook=Notebook, + panel=Panel, sizer=Sizer, + timer=Timer, fields=Fields0 ++ Fields1}}. create_sys_menu(Parent) -> - View = {"View", [#create_menu{id = ?ID_REFRESH, text = "Refresh"}, + View = {"View", [#create_menu{id = ?ID_REFRESH, text = "Refresh\tCtrl-R"}, #create_menu{id = ?ID_REFRESH_INTERVAL, text = "Refresh interval"}]}, observer_wx:create_menus(Parent, [View]). -update_syspage(#sys_wx_state{node = Node} = State) -> - Info = get_syspage_info(Node), - update_info_label(node_label, Info, State#sys_wx_state.node_label), - update_info_label(no_procs, Info, State#sys_wx_state.no_procs), - update_info_label(no_cpu, Info, State#sys_wx_state.no_cpu), - update_info_label(no_cpu_available, Info, State#sys_wx_state.no_cpu_available), - update_info_label(no_cpu_online, Info, State#sys_wx_state.no_cpu_online), - update_info_label(tot_alloc, Info, State#sys_wx_state.tot_alloc), - update_info_label(proc_used, Info, State#sys_wx_state.proc_used), - update_info_label(proc_alloc, Info, State#sys_wx_state.proc_alloc), - update_info_label(atom_used, Info, State#sys_wx_state.atom_used), - update_info_label(atom_alloc, Info, State#sys_wx_state.atom_alloc), - update_info_label(binary_alloc, Info, State#sys_wx_state.binary_alloc), - update_info_label(code_alloc, Info, State#sys_wx_state.code_alloc), - update_info_label(ets_alloc, Info, State#sys_wx_state.ets_alloc). - -update_info_label(node_label, Info, WxTxt) -> - wxStaticText:setLabel(WxTxt, observer_sys:node_name_str(Info)); -update_info_label(no_procs, Info, WxTxt) -> - wxStaticText:setLabel(WxTxt, observer_sys:no_procs_str(Info)); -update_info_label(no_cpu, Info, WxTxt) -> - wxStaticText:setLabel(WxTxt, observer_sys:no_cpu_str(Info)); -update_info_label(no_cpu_available, Info, WxTxt) -> - wxStaticText:setLabel(WxTxt, observer_sys:no_cpu_available_str(Info)); -update_info_label(no_cpu_online, Info, WxTxt) -> - wxStaticText:setLabel(WxTxt, observer_sys:no_cpu_online_str(Info)); -update_info_label(tot_alloc, Info, WxTxt) -> - wxStaticText:setLabel(WxTxt, observer_sys:tot_alloc_str(Info)); -update_info_label(proc_used, Info, WxTxt) -> - wxStaticText:setLabel(WxTxt, observer_sys:proc_used_str(Info)); -update_info_label(proc_alloc, Info, WxTxt) -> - wxStaticText:setLabel(WxTxt, observer_sys:proc_alloc_str(Info)); -update_info_label(atom_used, Info, WxTxt) -> - wxStaticText:setLabel(WxTxt, observer_sys:atom_used_str(Info)); -update_info_label(atom_alloc, Info, WxTxt) -> - wxStaticText:setLabel(WxTxt, observer_sys:atom_alloc_str(Info)); -update_info_label(binary_alloc, Info, WxTxt) -> - wxStaticText:setLabel(WxTxt, observer_sys:binary_alloc_str(Info)); -update_info_label(code_alloc, Info, WxTxt) -> - wxStaticText:setLabel(WxTxt, observer_sys:code_alloc_str(Info)); -update_info_label(ets_alloc, Info, WxTxt) -> - wxStaticText:setLabel(WxTxt, observer_sys:ets_alloc_str(Info)). +update_syspage(#sys_wx_state{node = Node, fields=Fields, sizer=Sizer}) -> + try + SysInfo = observer_wx:try_rpc(Node, ?MODULE, sys_info, []), + {Info, Stat} = info_fields(), + observer_lib:update_info(Fields, fill_info(Info, SysInfo) ++ fill_info(Stat, SysInfo)), + wxSizer:layout(Sizer) + catch E:R -> + io:format("~p:~p ~p~n",[E,R, erlang:get_stacktrace()]) + end, + ok. +info_fields() -> + Info = [{"System and Architecture", + [{"System Version", otp_release}, + {"Erts Version", version}, + {"Compiled for", system_architecture}, + {"Emulator Wordsize", wordsize_external}, + {"Process Wordsize", wordsize_internal}, + {"Smp Support", smp_support}, + {"Thread Support", threads}, + {"Async thread pool size", thread_pool_size} + ]}, + {"CPU's and Threads", + [{"System Logical CPU's", logical_processors}, + {"Erlang Logical CPU's", logical_processors_online}, + {"Used Logical CPU's", logical_processors_available} + ]} + ], + Stat = [{"Memory Usage", right, + [{"Total", total}, + {"Processes", processes}, + {"Atoms", atom}, + {"Binaries", binary}, + {"Code", code}, + {"Ets", ets} + ]}, + {"Statistics", right, + [{"Up time", uptime}, + {"Max Processes", process_limit}, + {"Processes", process_count}, + {"Run Queue", run_queue}, + {"IO Input", io_input}, + {"IO Output", io_output} + ]} + ], + {Info, Stat}. + +fill_info([{Str, Key}|Rest], Data) when is_atom(Key) -> + [{Str, proplists:get_value(Key,Data)} | fill_info(Rest, Data)]; +fill_info([{Str,SubStructure}|Rest], Data) -> + [{Str, fill_info(SubStructure, Data)}|fill_info(Rest,Data)]; +fill_info([{Str,Attrib,SubStructure}|Rest], Data) -> + [{Str, Attrib, fill_info(SubStructure, Data)}|fill_info(Rest,Data)]; +fill_info([], _) -> []. %%%%%%%%%%%%%%%%%%%%%%% Callbacks %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -216,45 +148,26 @@ handle_info({node, Node}, #sys_wx_state{panel = Panel} = State) -> try update_syspage(UpdState), {noreply, UpdState} - catch error:{badrpc, _} -> observer_wx:return_to_localnode(Panel, Node), {noreply, State} end; -handle_info({active, Node}, - #sys_wx_state{parent = Parent, - panel = Panel, - refr_timer = Timer0, - refr_intv = Intv} = State) -> +handle_info({active, Node}, #sys_wx_state{parent = Parent, panel = Panel, + timer = Timer} = State) -> UpdState = State#sys_wx_state{node = Node}, create_sys_menu(Parent), try update_syspage(UpdState), - Timer = case Timer0 of - true -> - {ok, Ref} = timer:send_interval(Intv*1000, refresh_interval), - Ref; - false -> - false - end, - {noreply, UpdState#sys_wx_state{refr_timer = Timer}} - + {noreply, UpdState#sys_wx_state{timer=observer_lib:start_timer(Timer)}} catch error:{badrpc, _} -> observer_wx:return_to_localnode(Panel, Node), {noreply, State} end; -handle_info(not_active, #sys_wx_state{refr_timer = Timer0} = State) -> - Timer = case Timer0 of - false -> false; - true -> true; - Timer0 -> - timer:cancel(Timer0), - true - end, - {noreply, State#sys_wx_state{refr_timer = Timer}}; +handle_info(not_active, #sys_wx_state{timer = Timer} = State) -> + {noreply, State#sys_wx_state{timer = observer_lib:stop_timer(Timer)}}; handle_info(Info, State) -> io:format("~p, ~p, Handle info: ~p~n", [?MODULE, ?LINE, Info]), @@ -286,28 +199,43 @@ handle_event(#wx{id = ?ID_REFRESH, event = #wxCommand{type = command_menu_select handle_event(#wx{id = ?ID_REFRESH_INTERVAL, event = #wxCommand{type = command_menu_selected}}, - #sys_wx_state{refr_timer = Timer0, - refr_intv = Intv0, - parent_notebook = Notebook} = State) -> - Parent = observer_tv_wx:get_wx_parent(Notebook), - case observer_tv_wx:interval_dialog(Parent, Timer0 /= false, Intv0, 1, 5*60) of - cancel -> - {noreply, State}; - {true, Intv} -> - case Timer0 of - false -> ok; - _ -> timer:cancel(Timer0) - end, - {ok, Timer} = timer:send_interval(Intv * 1000, refresh_interval), - {noreply, State#sys_wx_state{refr_timer=Timer, refr_intv=Intv}}; - {false, _} -> - case Timer0 of - false -> ok; - _ -> timer:cancel(Timer0) - end, - {noreply, State#sys_wx_state{refr_timer=false}} - end; + #sys_wx_state{timer = Timer0, parent_notebook = Notebook} = State) -> + Timer = observer_lib:interval_dialog(Notebook, Timer0, 1, 5*60), + {noreply, State#sys_wx_state{timer=Timer}}; handle_event(Event, State) -> io:format("handle event ~p\n", [Event]), {noreply, State}. + + +sys_info() -> + {{_,Input},{_,Output}} = erlang:statistics(io), + [{process_count, erlang:system_info(process_count)}, + {process_limit, erlang:system_info(process_limit)}, + {uptime, {time_ms, element(1, erlang:statistics(wall_clock))}}, + {run_queue, erlang:statistics(run_queue)}, + {io_input, {bytes, Input}}, + {io_output, {bytes, Output}}, + {logical_processors, erlang:system_info(logical_processors)}, + {logical_processors_available, erlang:system_info(logical_processors_available)}, + {logical_processors_online, erlang:system_info(logical_processors_online)}, + + {total, {bytes, erlang:memory(total)}}, + %%{processes_used, erlang:memory(processes_used)}, + {processes, {bytes, erlang:memory(processes)}}, + %%{atom_used, erlang:memory(atom_used)}, + {atom, {bytes, erlang:memory(atom)}}, + {binary, {bytes, erlang:memory(binary)}}, + {code, {bytes, erlang:memory(code)}}, + {ets, {bytes, erlang:memory(ets)}}, + + {otp_release, erlang:system_info(otp_release)}, + {version, erlang:system_info(version)}, + {system_architecture, erlang:system_info(system_architecture)}, + {kernel_poll, erlang:system_info(kernel_poll)}, + {smp_support, erlang:system_info(smp_support)}, + {threads, erlang:system_info(threads)}, + {thread_pool_size, erlang:system_info(thread_pool_size)}, + {wordsize_internal, erlang:system_info({wordsize, internal})}, + {wordsize_external, erlang:system_info({wordsize, external})} + ]. -- cgit v1.2.1