appmon.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,080 行 · 第 1/3 页
ERL
1,080 行
if Tag==time; Tag==queue -> {noreply, State#state{load_mode1=Tag}}; Tag==prog; Tag==linear -> {noreply, State#state{load_mode2=Tag}} end; %% Nodes menu item {node, Node, WinObj} -> %% Check first if this window is already displayed case get_win(Node, State#state.wins) of {ok, GUI} -> %% Node is already displayed, raise its window gs:config(GUI#win.window, raise), {noreply, State}; %% Node is not displayed false -> %% Redraw existing window or create a new window %% depending on window mode case State#state.window_mode of single -> {ok, GUI} = get_win2(WinObj, State#state.wins), %% Clear window and correct the node name draw_clear(GUI), GUI1 = draw_nodename(GUI, Node), %% Update window with the correct node name %% and the applications running at the node MNode = get_mnode(Node, State#state.mnodes), GUI2 = case MNode#mnode.status of dead -> display_nodedown(GUI1), GUI1; alive -> display_nodeup(GUI1, Node), draw_apps(GUI1, MNode#mnode.apps) end, Wins = replace_win(GUI#win.name, GUI2, State#state.wins), {noreply, State#state{wins=Wins}}; many -> GUI = draw_win(State#state.gs, Node), %% Update Nodes menu with all known nodes - %% use MNodes to get them in the right order lists:foreach(fun(MNode) -> Name = MNode#mnode.name, display_addnode(GUI, Name) end, State#state.mnodes), %% Mark selected options in the Options menu display_setopt(GUI, many), display_setopt(GUI, State#state.load_mode1), display_setopt(GUI, State#state.load_mode2), %% Add the applications running at the node MNode = get_mnode(Node, State#state.mnodes), GUI1 = case MNode#mnode.status of dead -> display_nodedown(GUI), GUI; alive -> display_nodeup(GUI, Node), draw_apps(GUI, MNode#mnode.apps) end, Wins = [GUI1|State#state.wins], {noreply, State#state{wins=Wins}} end end; %% Help menu = Help button help -> HelpFile = filename:join([code:lib_dir(appmon), "doc", "html", "part_frame.html"]), case State#state.wins of [Win] -> tool_utils:open_help(Win#win.window, HelpFile); _ -> tool_utils:open_help(State#state.gs, HelpFile) end, {noreply, State}; _Other -> {noreply, State} end;handle_info({gs, WinObj, configure, _, [WWindow, HWindow|_]}, State) -> {ok, GUI} = get_win2(WinObj, State#state.wins), GUI1 = draw_resize(GUI, WWindow, HWindow), display_scrollbar(GUI1), Wins = replace_win(GUI#win.name, GUI1, State#state.wins), {noreply, State#state{wins=Wins}};handle_info({gs, WinObj, destroy, _, _}, State) -> % OTP-1179 {ok, GUI} = get_win2(WinObj, State#state.wins), %% Terminate if this was the only open window case remove_win(GUI#win.name, State#state.wins) of [] -> {stop, normal, State}; Wins -> {noreply, State#state{wins=Wins}} end;handle_info(stop, State) -> {stop, normal, State};handle_info({'EXIT', Pid, Reason}, State) -> case Reason of shutdown -> %% Appmon is being asked to shut down, eg during reboot {stop, Reason, State}; _ -> case State#state.gs of %% GS exited, kill appmon {0, Pid} -> {stop, normal, State}; _ -> {noreply, State} end end;handle_info(_Info, State) -> {noreply, State}. %%----------------------------------------------------------------------%% Func: terminate/2%% Purpose: Shutdown the server%% Returns: any (ignored by gen_server)%%----------------------------------------------------------------------terminate(_Reason, State) -> bcast(State#state.mnodes, {kill}), appmon_lb:stop(State#state.lbpid), ok.%%----------------------------------------------------------------------%% Func: code_change/3%% Purpose: Convert process state when code is changed%% Returns: {ok, NewState}%%----------------------------------------------------------------------code_change(_OldVsn, State, _Extra) -> {ok, State}. %%%---------------------------------------------------------------------%%% Internal functions%%%---------------------------------------------------------------------%%----------------------------------------------------------------------%% MNode manipulating functions%%----------------------------------------------------------------------%% mk_mnodes(Nodes, LbPid) -> MNodes%% Nodes -> [atom()]%% LbPid -> pid()%% MNodes -> [#mnode{}]mk_mnodes([Node|Nodes], LbPid) -> [mk_mnode(Node, LbPid) | mk_mnodes(Nodes, LbPid)];mk_mnodes([], _LbPid) -> [].mk_mnode(Node, LbPid) -> %% Create an appmon process at the node {ok, Pid} = appmon_info:start_link(Node, self(), []), appmon_lb:add_node(LbPid, Node), appmon_info:load(Pid, Node, true, [{timeout,1000}]), appmon_info:app_ctrl(Pid, Node, true, []), #mnode{name=Node, status=alive, pid=Pid}.%% get_mnode(Node, MNodes) -> MNode | false%% Node -> atom()%% MNodes -> [#mnode{}]%% MNode -> #mnode{}get_mnode(Node, MNodes) -> case lists:keysearch(Node, #mnode.name, MNodes) of {value, MNode} -> MNode; false -> false end.%% replace_mnode(Node, MNode, MNodes1) -> Mnodes2%% Node -> atom()%% MNode -> #mnode{}%% MNodes1 -> MNodes2 -> [#mnode{}]%% Replaces, or adds if previously not included, the mnode with name%% Node in MNodes1 with MNode.replace_mnode(Node, MNode, [#mnode{name=Node} | MNodes]) -> [MNode | MNodes];replace_mnode(Node, MNode, [MNode2 | MNodes]) -> [MNode2 | replace_mnode(Node, MNode, MNodes)];replace_mnode(_Node, MNode, []) -> [MNode]. %%----------------------------------------------------------------------%% GUI list manipulating functions%%----------------------------------------------------------------------%% get_win(Node, Wins) -> Win%% Node -> atom()%% Wins -> [#win{}]%% Win -> #win{}get_win(Node, Wins) -> case lists:keysearch(Node, #win.name, Wins) of {value, Win} -> {ok, Win}; false -> false end.%% get_win2(WinObj, Wins) -> Win%% Window -> gsobj()%% Wins -> [#win{}]%% Win -> #win{}get_win2(WinObj, Wins) -> case lists:keysearch(WinObj, #win.window, Wins) of {value, Win} -> {ok, Win}; false -> false end.%% replace_win(Node, Win, Wins) -> Wins2%% Node -> atom()%% Win -> #win{}%% Wins -> Wins2 -> [#win{}]replace_win(Node, Win, Wins) -> lists:keyreplace(Node, #win.name, Wins, Win).%% remove_win(Node, Wins) -> Wins2%% Node -> atom()%% Wins -> Wins2 -> [#win{}]remove_win(Node, Wins) -> lists:keydelete(Node, #win.name, Wins).%%----------------------------------------------------------------------%% GUI manipulating functions%%-----------------------------------------------------------------------define(PAD, 10). % Pad between objects-define(PAD2, 4*?PAD). % Pad betw. node lbl and app-define(hMENUBAR, 25). % Note: Hardwired in Tcl/Tk-define(xNODELBL, 60). % Node label-define(yNODELBL, 35).-define(hNODELBL, 20).-define(xMETER, 5). % Meter-define(yMETER, ?yNODELBL).-define(wMETER, 20).-define(hMETER, ?hNODELBL + ?PAD + ?PAD2 + ?hBTN).-define(LEDCOUNT, 16).-define(xBTN, ?xNODELBL). % Application buttons-define(yBTN, ?yNODELBL + ?hNODELBL + ?PAD + ?PAD2).-define(wBTN, 70). % min width-define(hBTN, 20).-define(wCANVAS, 470 + ?wMETER + 3*?PAD). % Canvas-define(hCANVAS, ?yNODELBL + ?hNODELBL + ?PAD + ?PAD2 + ?hBTN + 2*?PAD).-define(wWIN, ?wCANVAS). % Window-define(hWIN, ?hMENUBAR + ?hCANVAS).%%--Main window---------------------------------------------------------draw_win(GS, Node) -> %% Main window NodeStr = atom_to_list(Node), Win = gs:create(window, GS, [{title, "APPMON: Overview on " ++ NodeStr}, {width, ?wWIN}, {height, ?hWIN}, {configure, true}]), Canvas = gs:create(canvas, Win, [{x, 0}, {y, ?hMENUBAR}, {width, ?wCANVAS}, {height, ?hCANVAS}]), L1 = gs:create(line, Canvas, [{coords, [{0,?yNODELBL-?PAD}, {?wCANVAS,?yNODELBL-?PAD}]}]), L2 = gs:create(line, Canvas, [{coords, [{0,?hCANVAS-?PAD}, {?wCANVAS,?hCANVAS-?PAD}]}]), %% Standard buttons MenuBar = gs:create(menubar, Win, [{height, ?hMENUBAR}]), FileMenuBtn = gs:create(menubutton, MenuBar, [{label, {text,"File"}}]), FileMenu = gs:create(menu, FileMenuBtn, []), gs:create(menuitem, FileMenu, [{label, {text,"Show List Box..."}}, {data, listbox}]), gs:create(menuitem, FileMenu, [{label, {text, "Close"}}, {data, {close, Win}}]), gs:create(menuitem, FileMenu, [{itemtype, separator}]), gs:create(menuitem, FileMenu, [{label, {text, "Exit"}}, {data, exit}]), ActionMenuBtn = gs:create(menubutton, MenuBar, [{label,{text,"Actions"}}]), ActionMenu = gs:create(menu, ActionMenuBtn, []), gs:create(menuitem, ActionMenu, [{label, {text,"Reboot"}}, {data, {action, reboot, Win}}]), gs:create(menuitem, ActionMenu, [{label, {text,"Restart"}}, {data, {action, restart, Win}}]), gs:create(menuitem, ActionMenu, [{label, {text,"Stop"}}, {data, {action, stop, Win}}]), gs:create(menuitem, ActionMenu, [{label, {text,"Ping"}}, {data, {action, ping, Win}}]), OptMenuBtn = gs:create(menubutton, MenuBar, [{label, {text,"Options"}}]), OptMenu = gs:create(menu, OptMenuBtn, []), G0 = now(), % Group identity unique per window! SMI = gs:create(menuitem, OptMenu, [{label, {text,"One window"}}, {itemtype, radio}, {group, G0}, {data, {window_mode, single}}]), MMI = gs:create(menuitem, OptMenu, [{label, {text,"Many windows"}}, {itemtype, radio}, {group, G0}, {data, {window_mode, many}}]), gs:create(menuitem, OptMenu, [{itemtype, separator}]), G1 = now(), TMI = gs:create(menuitem, OptMenu, [{label, {text,"Load: time"}}, {itemtype, radio}, {group, G1}, {data, {option, time, [{load_method,time}]}}]), QMI = gs:create(menuitem, OptMenu, [{label, {text,"Load: queue"}}, {itemtype, radio}, {group, G1}, {data, {option, queue, [{load_method,queue}]}}]), G2 = now(), PMI = gs:create(menuitem, OptMenu, [{label, {text,"Load: progressive"}}, {itemtype, radio}, {group, G2}, {data, {option, prog, [{load_scale,prog}]}}]),
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?