appmon_web.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,037 行 · 第 1/3 页

ERL
1,037
字号
%% ``The contents of this file are subject to the Erlang Public License,%% Version 1.1, (the "License"); you may not use this file except in%% compliance with the License. You should have received a copy of the%% Erlang Public License along with this software. If not, it can be%% retrieved via the world wide web at http://www.erlang.org/.%% %% Software distributed under the License is distributed on an "AS IS"%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See%% the License for the specific language governing rights and limitations%% under the License.%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %%     $Id$%%%%%---------------------------------------------------------------------%%% File    : webappmon.erl%%% Author  : Martin G. <marting@erix.ericsson.se>%%% Purpose : Frontend to the webbased version of appmon.%%% Created : 24 Apr 2001 by Martin G. <marting@erix.ericsson.se>%%%----------------------------------------------------------------------module(appmon_web).%% The functions that the user can call to interact with the genserver-export([init/1,handle_call/3,handle_cast/2,handle_info/2]).-export([terminate/2,code_change/3]).-export([node_info/2,application_info/2,application_env/2]).-export([proc_info/2,trace/2]).-export([start/0,stop/0,start_link/0]).%% Export the function that returns the configuration data needed by%% webtool-export([configData/0]).%% The following directive caters for (significantly) faster native%% code compilation of one function in this file by the HiPE compiler%% on register-poor architectures like the x86.-compile([{hipe,[{regalloc,graph_color}]}]).-behaviour(gen_server).%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Start the genserver                                                  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%start_link()->    gen_server:start_link({local,webappmon_server},appmon_web,[],[]).start()->    gen_server:start({local,webappmon_server},appmon_web,[],[]).%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Stop the genserver                                                   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% stop()->    gen_server:call(webappmon_server,stop,1000).%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Get the page that shows the nodes and the apps on the sel node       %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%node_info(Env,Input)->    gen_server:call(webappmon_server,{node_data,Env,Input}).%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Get the application process tree                                     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%application_info(Env,Input)->    gen_server:call(webappmon_server,{app_data,Env,Input}).%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Get the page that shows the data about the process                   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%proc_info(Env,Input)->    gen_server:call(webappmon_server,{proc_data,Env,Input}).%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Get the spec on the app                                              %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% application_env(Env,Input)->    gen_server:call(webappmon_server,{app_env,Env,Input}).%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Toggle the trace flag for the selected process                       %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%trace(Env,Input)->    gen_server:call(webappmon_server,{trace,Env,Input}).configData()->    {appmon,[{web_data,{"WebAppmon","/appmon/main_frame.html"}},	     	{alias,{"/appmon",code:priv_dir(appmon)}},		{alias,{erl_alias,"/erl",[appmon_web]}},		{start,{child,{backend,{process_info,start_link,[]},			       permanent,100,worker,[process_info]}}},	     {start,{child,{{local,webappmon_server},			    {appmon_web,start_link,[]},			    permanent,100,worker,[appmon_web]}}}	    ]}.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                                                                      %% Callback functions for the genserver                                 %%                                                                      %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%init(_Arg)->    {ok,[]}.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Create the different pages                                           %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%handle_call({node_data,_Env,Input},_From,State)->    {reply,app_and_node_sel_page(Input),State};handle_call({app_data,_Env,Input},_From,State)->    {reply,process_tree_page(Input),State};handle_call({proc_data,_Env,Input},_From,State)->    {reply,process_specifickation_page(Input),State};handle_call({app_env,_Env,Input},_From,State)->    {reply,application_specifickation_page(Input),State};handle_call({trace,_Env,Input},_From,State)->    {reply,toggle_trace(Input),State}.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Shutdown the genserver                                               %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%terminate(_,_State)->    ok.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Callback function currently not used ...                             %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%handle_cast(_,State)->    {noreply,State}.handle_info(_,State)->    {noreply,State}.code_change(_OldVsn,State,_Extra)->    {ok,State}.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                                                                    %%%% Private functions to create the part of the sides that is common   %%%% to all sides                                                       %%%%                                                                    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Create the Header for the page If we now the mimetype use that type%%%% otherwise use text                                                 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%header() ->    header("text/html").header(MimeType) ->    "Content-type: " ++ MimeType ++ "\r\n\r\n".%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Create the Htmlheader sett the title of the side to nothing if     %%%% we dont know the name of the side                                  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%html_header()->   html_header("").html_header(Part) ->        "<HTML BGCOLOR=\"#FFFFFF\">\n" ++	"<HEAD>\n" ++	"<TITLE>Appmon " ++ Part ++  "</TITLE>\n" ++	"</HEAD>\n".%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Close the Html tag and if neccessay add some clean upp             %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%html_end()->    "</HTML>".%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                                                                    %%%% The functions that creates the whole pages by collecting           %%%% the necessary data                                                 %%%%                                                                    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Returns the page where the user see's which nodes and apps that    %%%% are availible for monitoring                                       %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%app_and_node_sel_page(Input)->    [header(),     html_header(),     node_body(httpd:parse_query(Input)),     html_end()].%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Returns the process tree for the application whose name is         %%%% the first value in the Inputs key/value list                       %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%process_tree_page(Input)->    [header(),     html_header(),     application_javascript(httpd:parse_query(Input)),     application_body(httpd:parse_query(Input)),     html_end()].%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Send trace on or off to the process thats pid is the third arg of  %%%% the inputs key/val list. Then it returns the process tree for the  %%%% the application that is the first key/val pair of input            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%toggle_trace(Input)->   send_trace(httpd:parse_query(Input)),   [header(),    html_header(),     application_javascript(httpd:parse_query(Input)),     application_body(httpd:parse_query(Input)),    html_end()].%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Creates the page that shows all information about the process that %%%% that is the first arg of th input key/val pairs                    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%process_specifickation_page(Input)->    [header(),     html_header(),     process_body(httpd:parse_query(Input)),     html_end()].application_specifickation_page(Input)->    [header(),     html_header(),     application_env_body(httpd:parse_query(Input)),     html_end()].%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% The Private functions that do the job                              %%%% To build the the page that shows the applications                  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Build the body of the side that shows the node name and            %%%% the application list                                               %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%node_body([{"node",Node}|_Rest])->    case  process_info:is_node(Node) of	{true,Controlled_node,Name} ->	    "<BODY BGCOLOR=\"#FFFFFF\">" ++		node_selections_javascripts() ++		node_selection(Controlled_node) ++		node_title() ++		application_tree(Controlled_node,Name) ++		"</BODY>";	       	{false,Server_node,Name} ->	    "<BODY BGCOLOR=\"#FFFFFF\">" ++		node_selections_javascripts() ++		node_selection(Server_node) ++		node_title() ++		application_tree(Server_node,Name) ++		"</BODY>"    end;node_body(_Whatever)->    node_body([{atom_to_list(node),atom_to_list(node())}]).%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Returns the javascript that sets a new node to monitor             %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%node_selections_javascripts()->    "<SCRIPT>      function node_selected()      {                                              parent.frames.base_frames.location=\"../../appmon/start_info.html\"         window.location =\"./node_info?node=\" + " ++            "document.node_selection.nodes[document.node_selection.nodes.selectedIndex].value;      }      </SCRIPT>".%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Insert the html code that shows the combobox where the user can    %%%% select another node to monitor                                     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%node_selection(Node)->    " <FORM ACTION=\"./node_info\" NAME=node_selection>\n           <TABLE WIDTH=\"100%\" BORDER=\"0\">\n              <TR><TD ALIGN=\"center\">\n                   <SELECT NAME=nodes onChange=\"node_selected()\">\n" ++	print_nodes(order_nodes(Node,process_info:get_nodes())) ++	"</SELECT>\n              </TD></TR>\n            </TABLE>\n          </FORM>".    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Add the node we are working with in the beginning of the list and  %%%% remove it from other places so its always the first in the listbox %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%order_nodes(Node,Node_list)->    [Node|lists:delete(Node,Node_list)].%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Take the list of nodes and make it to a list of options to the     %%%% the combobox                                                       %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%print_nodes([])->    [];print_nodes([Node|Rest])->    "<OPTION value=\"" ++	atom_to_list(Node) ++	"\">" ++	atom_to_list(Node) ++	"\n" ++	print_nodes(Rest).%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Create the header of the node info page i.e. the name of the node  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%node_title()->   " <TABLE WIDTH=\"100%\" BORDER=\"0\">	<TR><TD ALIGN=\"center\"><FONT SIZE=5>Applications</FONT></TD></TR>    </TABLE>\n".%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Build the body of the side that shows the node i.e the application %%%% list                                                               %%%% Node and Node_name are the same just different types               %%%% Node are the atom  Node_name the string of the node name           %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%application_tree(Node,Node_name)->    Fun=fun(Name)->		Name_str =atom_to_list(Name),		"<LI><A HREF=\"./application_info?name=" ++ Name_str  ++		    "&mode=all&node=" ++ Node_name ++		    "\" TARGET=main><B>" ++ Name_str ++		    "</B></A>" ++ print_space(15-length(Name_str),[]) ++		    "<A HREF=\"./application_env?name=" ++ Name_str ++		    "&node=" ++ Node_name ++		    "\" TARGET=\"main\"><FONT SIZE=2>spec</FONT></A></LI>\n" 	end,    "<UL>" ++ 	lists:map(Fun, (process_info:get_applications(Node))) ++	"</UL>" ++

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?