otp_mib.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 198 行

ERL
198
字号
%% ``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$%%-module(otp_mib).%%%-----------------------------------------------------------------%%% Description: This module implements the OTP-MIB.%%% The tables are implemented as shadow tables with the module%%% snmp_shadow_table. %%%-----------------------------------------------------------------%% API-export([load/1, unload/1]).%% SNMP instrumentation-export([erl_node_table/1, erl_node_table/3, appl_table/1, appl_table/3]).%% SNMP shadow functions-export([update_erl_node_table/0, update_appl_table/0]).%% Exported for internal use via rpc-export([get_erl_node/1, get_appls/1]).%% Shadow tables  -record(erlNodeTable,	{erlNodeId, erlNodeName, erlNodeMachine, erlNodeVersion, 	 erlNodeRunQueue,         erlNodeRunTime, erlNodeWallClock, erlNodeReductions,	 erlNodeProcesses, erlNodeInBytes, erlNodeOutBytes}).-record(applTable, {key = '_', applName = '_', applDescr = '_',		    applVsn = '_'}).%% Shadow argument macros -define(erlNodeShadowArgs, 	{erlNodeTable, integer, record_info(fields, erlNodeTable), 5000,	 {otp_mib, update_erl_node_table}}). -define(applShadowArgs,	{applTable, {integer, integer}, record_info(fields, applTable), 	 5000, {otp_mib, update_appl_table}}).%% Misc-record(erlNodeAlloc, {nodeName, nodeId}).%%%=========================================================================%%%  API%%%=========================================================================%%-------------------------------------------------------------------------%% load(Agent) ->  ok | {error, Reason}%% Agent - pid() | atom()%% Reason - term()%% Description: Loads the OTP-MIB%%-------------------------------------------------------------------------load(Agent) ->    MibDir = code:priv_dir(otp_mibs) ++ "/mibs",    snmpa:load_mibs(Agent, [MibDir ++ "/OTP-MIB"]).%%-------------------------------------------------------------------------%% unload(Agent) ->  ok | {error, Reason}%% Agent - pid() | atom()%% Reason - term()%% Description: Loads the OTP-MIB%%-------------------------------------------------------------------------unload(Agent) ->    snmpa:unload_mibs(Agent, ["OTP-MIB"]).    %%%=========================================================================%%%  SNMP instrumentation%%%=========================================================================erl_node_table(new) ->    Tab = erlNodeAlloc,    Storage = ram_copies,     case lists:member(Tab, mnesia:system_info(tables)) of	true ->	    case mnesia:table_info(Tab, storage_type) of		unknown ->		    {atomic, ok} = mnesia:add_table_copy(Tab, node(), Storage);		Storage ->		    catch delete_all(Tab)	    end;	false ->	    Nodes = [node()],	    Props = [{type, set},		     {attributes, record_info(fields, erlNodeAlloc)},		     {local_content, true},		     {Storage, Nodes}],	    {atomic, ok} = mnesia:create_table(Tab, Props)        end,    ok = mnesia:dirty_write({erlNodeAlloc, next_index, 1}),    update_node_alloc([node() | nodes()]),    snmp_shadow_table:table_func(new, ?erlNodeShadowArgs).    erl_node_table(Op, RowIndex, Cols) ->    snmp_shadow_table:table_func(Op, RowIndex, Cols, ?erlNodeShadowArgs).appl_table(Op) ->    snmp_shadow_table:table_func(Op, ?applShadowArgs).appl_table(Op, RowIndex, Cols) ->    snmp_shadow_table:table_func(Op, RowIndex, Cols, ?applShadowArgs).%%%=========================================================================%%%  SNMP shadow functions%%%=========================================================================update_erl_node_table() ->    delete_all(erlNodeTable),    Nodes = [node() | nodes()],    update_node_alloc(Nodes),    lists:foreach(      fun(Node) ->	      [{_,_,Idx}] = mnesia:dirty_read({erlNodeAlloc, Node}),	      ErlNode = rpc:call(Node, otp_mib, get_erl_node, [Idx]),	      ok = mnesia:dirty_write(ErlNode)      end, Nodes).update_appl_table() ->    delete_all(applTable),    Nodes = [node() | nodes()],    update_node_alloc(Nodes),    lists:foreach(      fun(Node) ->	      [{_,_,Idx}] = mnesia:dirty_read({erlNodeAlloc, Node}),	      Appls = rpc:call(Node, otp_mib, get_appls, [Idx]),	      lists:foreach(fun(Appl) ->				    ok = mnesia:dirty_write(Appl)			    end, Appls)      end, Nodes).%%%========================================================================%%% Exported for internal use via rpc%%%========================================================================get_erl_node(Id) ->    IO = erlang:statistics(io),    #erlNodeTable{erlNodeId = Id,		  erlNodeName = atom_to_list(node()),		  erlNodeVersion = erlang:system_info(version),		  erlNodeMachine = erlang:system_info(machine),		  erlNodeRunQueue = erlang:statistics(run_queue),		  erlNodeRunTime = element(1, erlang:statistics(runtime)),		  erlNodeWallClock = 		  element(1, erlang:statistics(wall_clock)),		  erlNodeReductions = 		  element(1, erlang:statistics(reductions)),		  erlNodeProcesses = length(processes()),		  erlNodeInBytes = element(2, element(1, IO)),		  erlNodeOutBytes = element(2, element(2, IO))}.    get_appls(NodeId) ->    element(1,	    lists:mapfoldl(	      fun({ApplName, ApplDescr, ApplVsn}, ApplId) ->		      {#applTable{key = {NodeId, ApplId},				  applName = atom_to_list(ApplName),				  applDescr = ApplDescr,				  applVsn = ApplVsn},		       ApplId + 1}	      end, 1, application:which_applications())).%%%========================================================================%%% Internal functions%%%========================================================================update_node_alloc([Node | T]) ->    case mnesia:dirty_read({erlNodeAlloc, Node}) of	[] ->	    [{_, _, Idx}] = mnesia:dirty_read({erlNodeAlloc, next_index}),	    ok = mnesia:dirty_write(#erlNodeAlloc{nodeName = Node, 						  nodeId = Idx}),	    ok = mnesia:dirty_write({erlNodeAlloc, next_index, Idx + 1});	_ ->	    ok    end,    update_node_alloc(T);update_node_alloc([]) -> ok.delete_all(Name) -> delete_all(mnesia:dirty_first(Name), Name).delete_all('$end_of_table', _Name) -> done;delete_all(Key, Name) ->    Next = mnesia:dirty_next(Name, Key),    ok = mnesia:dirty_delete({Name, Key}),    delete_all(Next, Name).

⌨️ 快捷键说明

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