From a793ab815d0c828fb1ef7ba72ab58c1b45542831 Mon Sep 17 00:00:00 2001 From: Tobias Schlager Date: Tue, 16 Jul 2013 11:44:42 +0200 Subject: [otp_mibs] Update types of applicable MIB objects to 64bit based types. --- lib/otp_mibs/mibs/OTP-EVA-MIB.mib | 10 +++++----- lib/otp_mibs/mibs/OTP-MIB.mib | 30 ++++++++++++++++++------------ lib/otp_mibs/mibs/OTP-REG.mib | 8 ++++---- lib/otp_mibs/mibs/OTP-TC.mib | 6 +++--- 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/lib/otp_mibs/mibs/OTP-EVA-MIB.mib b/lib/otp_mibs/mibs/OTP-EVA-MIB.mib index 6fbb8ef073..2815251c23 100644 --- a/lib/otp_mibs/mibs/OTP-EVA-MIB.mib +++ b/lib/otp_mibs/mibs/OTP-EVA-MIB.mib @@ -34,7 +34,7 @@ IMPORTS ; otpEvaModule MODULE-IDENTITY - LAST-UPDATED "0305090900Z" + LAST-UPDATED "200305090900Z" ORGANIZATION "Ericsson" CONTACT-INFO "Contact: Erlang Support see license agreement for Erlang/OTP." @@ -42,19 +42,19 @@ otpEvaModule MODULE-IDENTITY "This MIB is part of the OTP MIB. It defines MIB objects for the eva application in OTP." - REVISION "0305090900Z" + REVISION "200305090900Z" DESCRIPTION "Changed CONTACT-INFO as it was outdated, made it more generic to avoid such changes in the future." - REVISION "9801270900Z" + REVISION "199801270900Z" DESCRIPTION "Changed erroneous defintion of alarmCleared notification. Changed erroneous name of this module to otpEvaModule." - REVISION "9712010900Z" + REVISION "199712010900Z" DESCRIPTION "Converted to v2 SMI and placed in the OTP tree." - REVISION "9705020900Z" + REVISION "199705020900Z" DESCRIPTION "The initial version of this MIB module. It is very much inspired by the ANS-ALM-MIB and Axd301Eva-OMS mibs." diff --git a/lib/otp_mibs/mibs/OTP-MIB.mib b/lib/otp_mibs/mibs/OTP-MIB.mib index 2d4c286bc7..22dc21c9c5 100644 --- a/lib/otp_mibs/mibs/OTP-MIB.mib +++ b/lib/otp_mibs/mibs/OTP-MIB.mib @@ -21,7 +21,7 @@ OTP-MIB DEFINITIONS ::= BEGIN IMPORTS MODULE-IDENTITY, OBJECT-TYPE, - Counter32, Gauge32, Integer32 + Counter64, Gauge32, Integer32 FROM SNMPv2-SMI TEXTUAL-CONVENTION, DisplayString FROM SNMPv2-TC @@ -32,7 +32,7 @@ IMPORTS ; otpModule MODULE-IDENTITY - LAST-UPDATED "0305090900Z" + LAST-UPDATED "201307160700Z" ORGANIZATION "Ericsson" CONTACT-INFO "Contact: Erlang Support see license agreement for Erlang/OTP." @@ -41,16 +41,22 @@ otpModule MODULE-IDENTITY agent executing at one node only. Each Erlang node in the OTP system is represented by one row in the erlNodeTable." - REVISION "0305090900Z" + REVISION "201307160700Z" + DESCRIPTION + "Updated various types to be able to reflect larger values. + The objects erlNodeReductions, erlNodeInBytes, erlNodeOutBytes as well + as the type MilliSeconds have been updated to Counter64." + + REVISION "200305090900Z" DESCRIPTION "Changed CONTACT-INFO as it was outdated, made it more generic to avoid such changes in the future." - REVISION "9712010900Z" + REVISION "199712010900Z" DESCRIPTION "Converted to v2 SMI and placed in the OTP tree." - REVISION "9608191700Z" + REVISION "199608191700Z" DESCRIPTION "The initial revision of MIB module OTP-MIB." @@ -70,7 +76,7 @@ MilliSeconds ::= TEXTUAL-CONVENTION the time, in milliseconds between two epochs. When objects are defined which use this type, the description of the object identifies both of the reference epochs." - SYNTAX Counter32 + SYNTAX Counter64 -- Managed Objects @@ -103,10 +109,10 @@ ErlNodeEntry ::= SEQUENCE { erlNodeRunQueue Gauge32, erlNodeRunTime MilliSeconds, erlNodeWallClock MilliSeconds, - erlNodeReductions Counter32, + erlNodeReductions Counter64, erlNodeProcesses Gauge32, - erlNodeInBytes Counter32, - erlNodeOutBytes Counter32 + erlNodeInBytes Counter64, + erlNodeOutBytes Counter64 } erlNodeId OBJECT-TYPE @@ -168,7 +174,7 @@ erlNodeWallClock OBJECT-TYPE ::= { erlNodeEntry 7 } erlNodeReductions OBJECT-TYPE - SYNTAX Counter32 + SYNTAX Counter64 MAX-ACCESS read-only STATUS current DESCRIPTION @@ -184,7 +190,7 @@ erlNodeProcesses OBJECT-TYPE ::= { erlNodeEntry 9 } erlNodeInBytes OBJECT-TYPE - SYNTAX Counter32 + SYNTAX Counter64 MAX-ACCESS read-only STATUS current DESCRIPTION @@ -192,7 +198,7 @@ erlNodeInBytes OBJECT-TYPE ::= { erlNodeEntry 10 } erlNodeOutBytes OBJECT-TYPE - SYNTAX Counter32 + SYNTAX Counter64 MAX-ACCESS read-only STATUS current DESCRIPTION diff --git a/lib/otp_mibs/mibs/OTP-REG.mib b/lib/otp_mibs/mibs/OTP-REG.mib index c6ef2c67e5..c700f93fd8 100644 --- a/lib/otp_mibs/mibs/OTP-REG.mib +++ b/lib/otp_mibs/mibs/OTP-REG.mib @@ -25,25 +25,25 @@ IMPORTS ; otpRegModule MODULE-IDENTITY - LAST-UPDATED "0305090900Z" + LAST-UPDATED "200305090900Z" ORGANIZATION "Ericsson" CONTACT-INFO "Contact: Erlang Support see license agreement for Erlang/OTP." DESCRIPTION "The root MIB module for OTP." - REVISION "0305090900Z" + REVISION "200305090900Z" DESCRIPTION "Changed CONTACT-INFO as it was outdated, made it more generic to avoid such changes in the future." - REVISION "9902020900Z" + REVISION "199902020900Z" DESCRIPTION "Cleaned up OBJECT IDENTIFIER registration. Changed the name of the MODULE-IDENTITY of this module to non-conflicting name otpRegModule." - REVISION "9712010900Z" + REVISION "199712010900Z" DESCRIPTION "The initial revision of MIB module OTP-REG." ::= { otpModules 1 } diff --git a/lib/otp_mibs/mibs/OTP-TC.mib b/lib/otp_mibs/mibs/OTP-TC.mib index 38c4d05846..9b80e1ccac 100644 --- a/lib/otp_mibs/mibs/OTP-TC.mib +++ b/lib/otp_mibs/mibs/OTP-TC.mib @@ -29,7 +29,7 @@ IMPORTS ; otpTcModule MODULE-IDENTITY - LAST-UPDATED "0305090900Z" + LAST-UPDATED "200305090900Z" ORGANIZATION "Ericsson" CONTACT-INFO "Contact: Erlang Support see license agreement for Erlang/OTP." @@ -37,13 +37,13 @@ otpTcModule MODULE-IDENTITY "This MIB is part of the OTP MIB. It defines common Textual Conventions used in other OTP mib modules." - REVISION "0305090900Z" + REVISION "200305090900Z" DESCRIPTION "Changed CONTACT-INFO as it was outdated, made it more generic to avoid such changes in the future." - REVISION "9712010900Z" + REVISION "199712010900Z" DESCRIPTION "The initial version of this module." ::= { otpModules 2 } -- cgit v1.2.3 From b183cadcaddde7dc903c3fa5540c55e3f1408595 Mon Sep 17 00:00:00 2001 From: Tobias Schlager Date: Tue, 16 Jul 2013 11:46:58 +0200 Subject: [otp_mibs] Add test suite for range checks and reduction value overflow. --- lib/otp_mibs/test/Makefile | 85 ++++++++++++ lib/otp_mibs/test/otp_mibs_SUITE.cfg | 15 +++ lib/otp_mibs/test/otp_mibs_SUITE.erl | 245 +++++++++++++++++++++++++++++++++++ 3 files changed, 345 insertions(+) create mode 100644 lib/otp_mibs/test/Makefile create mode 100644 lib/otp_mibs/test/otp_mibs_SUITE.cfg create mode 100644 lib/otp_mibs/test/otp_mibs_SUITE.erl diff --git a/lib/otp_mibs/test/Makefile b/lib/otp_mibs/test/Makefile new file mode 100644 index 0000000000..48c1c5c7d8 --- /dev/null +++ b/lib/otp_mibs/test/Makefile @@ -0,0 +1,85 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 1997-2012. All Rights Reserved. +# +# 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 online 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. +# +# %CopyrightEnd% +# +include $(ERL_TOP)/make/target.mk + +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- + +MODULES= otp_mibs_SUITE + +EBIN = . + +HRL_FILES= + +ERL_FILES= $(MODULES:%=%.erl) + +TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR)) + +SOURCE = $(ERL_FILES) $(HRL_FILES) + +EMAKEFILE=Emakefile + +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/otp_mibs_test + +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- +ERL_MAKE_FLAGS += +ERL_COMPILE_FLAGS += \ + -I$(ERL_TOP)/lib/test_server/include \ + -I$(ERL_TOP)/lib/snmp/include + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- + +make_emakefile: + $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES)\ + > $(EMAKEFILE) + +tests debug opt: make_emakefile + erl $(ERL_MAKE_FLAGS) -make + +clean: + rm -f $(EMAKEFILE) + rm -f $(TARGET_FILES) + rm -f core *~ + +docs: + + +# ---------------------------------------------------- +# Release Target +# ---------------------------------------------------- +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: + +release_tests_spec: make_emakefile + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) $(EMAKEFILE) $(SOURCE) "$(RELSYSDIR)" + $(INSTALL_DATA) otp_mibs_SUITE.cfg "$(RELSYSDIR)" + +release_docs_spec: diff --git a/lib/otp_mibs/test/otp_mibs_SUITE.cfg b/lib/otp_mibs/test/otp_mibs_SUITE.cfg new file mode 100644 index 0000000000..d01cf92104 --- /dev/null +++ b/lib/otp_mibs/test/otp_mibs_SUITE.cfg @@ -0,0 +1,15 @@ +%% -*- erlang -*- +{snmp, + [ + {start_agent,true}, + {users, + [ + {otp_mibs_test,[snmpm_user_default,[]]} + ]}, + {managed_agents, + [ + {otp_mibs_test, [otp_mibs_test, {127,0,0,1}, 4000, []]} + ]}, + {agent_sysname,"Test otp_mibs"}, + {mgr_port,5001} + ]}. diff --git a/lib/otp_mibs/test/otp_mibs_SUITE.erl b/lib/otp_mibs/test/otp_mibs_SUITE.erl new file mode 100644 index 0000000000..5fd52ac2ac --- /dev/null +++ b/lib/otp_mibs/test/otp_mibs_SUITE.erl @@ -0,0 +1,245 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2012. All Rights Reserved. +%% +%% 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 online 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. +%% +%% %CopyrightEnd% +%% +-module(otp_mibs_SUITE). + +%%----------------------------------------------------------------- +%% This suite can no longer be executed standalone, i.e. it must be +%% executed with common test. The reason is that ct_snmp is used +%% instead of the snmp application directly. The suite requires a +%% config file, otp_mibs_SUITE.cfg, found in the same directory as +%% the suite. +%% +%% Execute with: +%% > ct_run -suite otp_mibs_SUITE -config otp_mibs_SUITE.cfg +%%----------------------------------------------------------------- + +-include_lib("test_server/include/test_server.hrl"). +-include_lib("otp_mibs/include/OTP-MIB.hrl"). +-include_lib("snmp/include/snmp_types.hrl"). + +% Test server specific exports +-export([all/0, + suite/0, + groups/0, + init_per_group/2, + end_per_group/2, + init_per_suite/1, + end_per_suite/1, + init_per_testcase/2, + end_per_testcase/2]). + +% Test cases must be exported. +-export([nt_basic_types/1, nt_high_reduction_count/1]). + +-define(TRAP_UDP, 5000). +-define(AGENT_UDP, 4000). +-define(CONF_FILE_VER, [v2]). +-define(SYS_NAME, "Test otp_mibs"). +-define(MAX_MSG_SIZE, 484). +-define(ENGINE_ID, "mgrEngine"). +-define(MGR_PORT, 5001). + +%% Since some cases are only interested in single entries of the OTP-MIB's +%% node table, one row must be chosen. The first row should be sufficient +%% for this. +-define(NODE_ENTRY, 1). + +%%--------------------------------------------------------------------- +%% CT setup +%%--------------------------------------------------------------------- + +init_per_testcase(_Case, Config) when is_list(Config) -> + Dog = test_server:timetrap(test_server:minutes(6)), + [{watchdog, Dog}|Config]. + +end_per_testcase(_Case, Config) when is_list(Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + Config. + +suite() -> [{ct_hooks,[ts_install_cth]}, {require, snmp_mgr_agent, snmp}]. + +all() -> [{group, node_table}]. + +groups() -> [{node_table, [], [nt_basic_types, nt_high_reduction_count]}]. + +init_per_group(_GroupName, Config) -> Config. + +end_per_group(_GroupName, Config) -> Config. + +init_per_suite(Config) -> + ?line application:start(sasl), + ?line application:start(mnesia), + ?line application:start(otp_mibs), + + ok = ct_snmp:start(Config,snmp_mgr_agent), + + %% Load the mibs that should be tested + otp_mib:load(snmp_master_agent), + + Config. + +end_per_suite(Config) -> + PrivDir = ?config(priv_dir, Config), + ConfDir = filename:join(PrivDir,"conf"), + DbDir = filename:join(PrivDir,"db"), + MgrDir = filename:join(PrivDir, "mgr"), + + %% Uload mibs + otp_mib:unload(snmp_master_agent), + + %% Clean up + application:stop(snmp), + application:stop(mnesia), + application:stop(otp_mibs), + + del_dir(ConfDir), + del_dir(DbDir), + (catch del_dir(MgrDir)), + ok. + +%%--------------------------------------------------------------------- +%% Test cases +%%--------------------------------------------------------------------- + +nt_basic_types(suite) -> + []; +nt_basic_types(doc) -> + ["Query every item of the node table and check its variable " + "type and content for sensible values."]; +nt_basic_types(Config) when is_list(Config) -> + ok = otp_mib:update_erl_node_table(), + + NodeNameId = ?erlNodeEntry ++ [?erlNodeName, ?NODE_ENTRY], + {noError, 0, [NodeNameVal]} = snmp_get([NodeNameId]), + #varbind{variabletype = 'OCTET STRING'} = NodeNameVal, + true = is_list(NodeNameVal#varbind.value), + + NodeMachineId = ?erlNodeEntry ++ [?erlNodeMachine, ?NODE_ENTRY], + {noError, 0, [NodeMachineVal]} = snmp_get([NodeMachineId]), + #varbind{variabletype = 'OCTET STRING'} = NodeMachineVal, + true = is_list(NodeMachineVal#varbind.value), + + NodeVersionId = ?erlNodeEntry ++ [?erlNodeVersion, ?NODE_ENTRY], + {noError, 0, [NodeVersionVal]} = snmp_get([NodeVersionId]), + #varbind{variabletype = 'OCTET STRING'} = NodeVersionVal, + true = is_list(NodeVersionVal#varbind.value), + + NodeRunQueueId = ?erlNodeEntry ++ [?erlNodeRunQueue, ?NODE_ENTRY], + {noError, 0, [NodeRunQueueVal]} = snmp_get([NodeRunQueueId]), + #varbind{variabletype = 'Unsigned32'} = NodeRunQueueVal, + true = is_integer(NodeRunQueueVal#varbind.value), + NodeRunQueueVal#varbind.value >= 0, + NodeRunQueueVal#varbind.value =< 4294967295, + + NodeRunTimeId = ?erlNodeEntry ++ [?erlNodeRunTime, ?NODE_ENTRY], + {noError, 0, [NodeRunTimeVal]} = snmp_get([NodeRunTimeId]), + #varbind{variabletype = 'Counter64'} = NodeRunTimeVal, + true = is_integer(NodeRunTimeVal#varbind.value), + NodeRunTimeVal#varbind.value >= 0, + NodeRunTimeVal#varbind.value =< 18446744073709551615, + + NodeWallClockId = ?erlNodeEntry ++ [?erlNodeWallClock, ?NODE_ENTRY], + {noError, 0, [NodeWallClockVal]} = snmp_get([NodeWallClockId]), + #varbind{variabletype = 'Counter64'} = NodeWallClockVal, + true = is_integer(NodeWallClockVal#varbind.value), + NodeWallClockVal#varbind.value >= 0, + NodeWallClockVal#varbind.value =< 18446744073709551615, + + NodeReductionsId = ?erlNodeEntry ++ [?erlNodeReductions, ?NODE_ENTRY], + {noError, 0, [NodeReductionsVal]} = snmp_get([NodeReductionsId]), + #varbind{variabletype = 'Counter64'} = NodeReductionsVal, + true = is_integer(NodeReductionsVal#varbind.value), + NodeReductionsVal#varbind.value >= 0, + NodeReductionsVal#varbind.value =< 18446744073709551615, + + NodeProcessesId = ?erlNodeEntry ++ [?erlNodeProcesses, ?NODE_ENTRY], + {noError, 0, [NodeProcessesVal]} = snmp_get([NodeProcessesId]), + #varbind{variabletype = 'Unsigned32'} = NodeProcessesVal, + true = is_integer(NodeProcessesVal#varbind.value), + NodeProcessesVal#varbind.value >= 0, + NodeProcessesVal#varbind.value =< 4294967295, + + NodeInBytesId = ?erlNodeEntry ++ [?erlNodeInBytes, ?NODE_ENTRY], + {noError, 0, [NodeInBytesVal]} = snmp_get([NodeInBytesId]), + #varbind{variabletype = 'Counter64'} = NodeInBytesVal, + true = is_integer(NodeInBytesVal#varbind.value), + NodeInBytesVal#varbind.value >= 0, + NodeInBytesVal#varbind.value =< 18446744073709551615, + + NodeOutBytesId = ?erlNodeEntry ++ [?erlNodeOutBytes, ?NODE_ENTRY], + {noError, 0, [NodeOutBytesVal]} = snmp_get([NodeOutBytesId]), + #varbind{variabletype = 'Counter64'} = NodeOutBytesVal, + true = is_integer(NodeOutBytesVal#varbind.value), + NodeOutBytesVal#varbind.value >= 0, + NodeOutBytesVal#varbind.value =< 18446744073709551615, + + ok. + +nt_high_reduction_count(suite) -> + []; +nt_high_reduction_count(doc) -> + ["Check that no error occurs when the erlNodeReductions field" + "exceeds the 32bit boundary, this may take about 10min."]; +nt_high_reduction_count(Config) when is_list(Config) -> + NodeReductions = ?erlNodeEntry ++ [?erlNodeReductions, ?NODE_ENTRY], + + BumpFun = fun(F, Limit) -> + case erlang:statistics(reductions) of + {Total, _} when Total < Limit -> + F(F, Limit); + _ -> + ok + end + end, + + ok = otp_mib:update_erl_node_table(), + + {noError, 0, [StartVal]} = snmp_get([NodeReductions]), + #varbind{variabletype = 'Counter64'} = StartVal, + true = is_integer(StartVal#varbind.value), + StartVal#varbind.value >= 0, + case StartVal#varbind.value =< 4294967295 of + true -> + ok = otp_mib:update_erl_node_table(), + BumpFun(BumpFun, 4294967295), + {noError, 0, [EndVal]} = snmp_get([NodeReductions]), + #varbind{variabletype = 'Counter64'} = EndVal, + true = is_integer(EndVal#varbind.value), + EndVal#varbind.value >= 4294967295, + EndVal#varbind.value =< 18446744073709551615; + false -> + %% no need to bump more reductions, since the initial get + %% command already returned successfully with a large value + ok + end. + +%%--------------------------------------------------------------------- +%% Internal functions +%%--------------------------------------------------------------------- + +snmp_get(OIdList) -> + ct_snmp:get_values(otp_mibs_test, OIdList, snmp_mgr_agent). + +del_dir(Dir) -> + io:format("Deleting: ~s~n",[Dir]), + {ok, Files} = file:list_dir(Dir), + FullPathFiles = lists:map(fun(File) -> filename:join(Dir, File) end, Files), + lists:foreach(fun file:delete/1, FullPathFiles), + file:del_dir(Dir). -- cgit v1.2.3 From 92fa944c70d5eb2ce8585004c947dbe958d37cfd Mon Sep 17 00:00:00 2001 From: Tobias Schlager Date: Tue, 16 Jul 2013 11:48:10 +0200 Subject: [otp_mibs] Add type based integer value truncation/reset. This fixes errors when querying e.g. the erlNodeReductions, erlNodeInBytes and erlNodeOutBytes objects in long-running Erlang/OTP systems. --- lib/otp_mibs/src/otp_mib.erl | 69 +++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 26 deletions(-) diff --git a/lib/otp_mibs/src/otp_mib.erl b/lib/otp_mibs/src/otp_mib.erl index 619104007c..9d52ce1fab 100644 --- a/lib/otp_mibs/src/otp_mib.erl +++ b/lib/otp_mibs/src/otp_mib.erl @@ -1,26 +1,26 @@ %% %% %CopyrightBegin% -%% +%% %% Copyright Ericsson AB 1996-2011. All Rights Reserved. -%% +%% %% 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 online 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. -%% +%% %% %CopyrightEnd% %% -module(otp_mib). %%%----------------------------------------------------------------- %%% Description: This module implements the OTP-MIB. %%% The tables are implemented as shadow tables with the module -%%% snmp_shadow_table. +%%% snmp_shadow_table. %%%----------------------------------------------------------------- %% API @@ -35,9 +35,9 @@ %% Exported for internal use via rpc -export([get_erl_node/1, get_appls/1]). -%% Shadow tables +%% Shadow tables -record(erlNodeTable, - {erlNodeId, erlNodeName, erlNodeMachine, erlNodeVersion, + {erlNodeId, erlNodeName, erlNodeMachine, erlNodeVersion, erlNodeRunQueue, erlNodeRunTime, erlNodeWallClock, erlNodeReductions, erlNodeProcesses, erlNodeInBytes, erlNodeOutBytes}). @@ -45,13 +45,13 @@ -record(applTable, {key = '_', applName = '_', applDescr = '_', applVsn = '_'}). -%% Shadow argument macros --define(erlNodeShadowArgs, +%% Shadow argument macros +-define(erlNodeShadowArgs, {erlNodeTable, integer, record_info(fields, erlNodeTable), 5000, fun otp_mib:update_erl_node_table/0}). -define(applShadowArgs, - {applTable, {integer, integer}, record_info(fields, applTable), + {applTable, {integer, integer}, record_info(fields, applTable), 5000, fun otp_mib:update_appl_table/0}). %% Misc @@ -79,14 +79,14 @@ load(Agent) -> %%------------------------------------------------------------------------- unload(Agent) -> snmpa:unload_mibs(Agent, ["OTP-MIB"]). - + %%%========================================================================= %%% SNMP instrumentation %%%========================================================================= erl_node_table(new) -> Tab = erlNodeAlloc, - Storage = ram_copies, + Storage = ram_copies, case lists:member(Tab, mnesia:system_info(tables)) of true -> case mnesia:table_info(Tab, storage_type) of @@ -101,12 +101,12 @@ erl_node_table(new) -> {attributes, record_info(fields, erlNodeAlloc)}, {local_content, true}, {Storage, Nodes}], - {atomic, ok} = mnesia:create_table(Tab, Props) + {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). @@ -148,21 +148,26 @@ update_appl_table() -> %%% Exported for internal use via rpc %%%======================================================================== get_erl_node(Id) -> + RunQueue = erlang:statistics(run_queue), + RunTime = element(1, erlang:statistics(runtime)), + WallClock = element(1, erlang:statistics(wall_clock)), + Reductions = element(1, erlang:statistics(reductions)), + Processes = length(processes()), IO = erlang:statistics(io), - #erlNodeTable{erlNodeId = Id, + InBytes = element(2, element(1, IO)), + OutBytes = element(2, element(2, IO)), + #erlNodeTable{erlNodeId = truncate_int('Integer32', 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))}. - + erlNodeRunQueue = truncate_int('Unsigned32', RunQueue), + erlNodeRunTime = truncate_int('Counter64', RunTime), + erlNodeWallClock = truncate_int('Counter64', WallClock), + erlNodeReductions = truncate_int('Counter64', Reductions), + erlNodeProcesses = truncate_int('Unsigned32', Processes), + erlNodeInBytes = truncate_int('Counter64', InBytes), + erlNodeOutBytes = truncate_int('Counter64', OutBytes)}. + get_appls(NodeId) -> element(1, lists:mapfoldl( @@ -181,7 +186,7 @@ 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, + ok = mnesia:dirty_write(#erlNodeAlloc{nodeName = Node, nodeId = Idx}), ok = mnesia:dirty_write({erlNodeAlloc, next_index, Idx + 1}); _ -> @@ -196,3 +201,15 @@ delete_all(Key, Name) -> Next = mnesia:dirty_next(Name, Key), ok = mnesia:dirty_delete({Name, Key}), delete_all(Next, Name). + +%% This will return a value limited to fit into the specified type. +%% While counter types will be resetted, other integer types will +%% only be restricted to the valid range. +truncate_int('Counter64', Value) when Value < 0 -> 0; +truncate_int('Counter64', Value) -> Value rem 18446744073709551615; +truncate_int('Unsigned32', Value) when Value < 0 -> 0; +truncate_int('Unsigned32', Value) when Value > 4294967295 -> 4294967295; +truncate_int('Unsigned32', Value) -> Value; +truncate_int('Integer32', Value) when Value < -2147483648 -> -2147483648; +truncate_int('Integer32', Value) when Value > 2147483647 -> 2147483647; +truncate_int('Integer32', Value) -> Value. -- cgit v1.2.3