We occasionally make mnesia data readable via SNMP. Here's a cookbook summary of the process. Certainly the Ericsson guide listed in the references should be consulted - this page merely gives extensive detail for a sample case.
Complete directions are given for creating a sample table, configuring the MIB, relating the two, and accessing the table from a net-snmp client.
Limitations of this tutorial.
Code was compiled and executed using FreeBSD-5.0, OTP-R9B1, and Net-SNMP-5.0.8_1.
For this example, use a table for several servers which handle telephone calls. Each row contains the server name, plus two counters - the number of inbound calls and the number of outbound calls. Here's an .hrl file defining the record type:
This example places the monitored data in the SNMP OID tree under iso.org.dod.internet.private.enterprises. Filename must end with ".mib". We use a fictional enterprise name of "bazmatic" with enterprise number 99999. See references below if you need an official enterprise number. Server names will be read-only from SNMP. Call counters will be writable from SNMP.
Since default mnesia functions are used, this step could probably be omitted if RowStatus were used.
Shell command for compiling the MIB.
/usr/home/xxx/otp-snmp>erl
Erlang (BEAM) emulator version 5.2.3.3 [source] [hipe] [threads:0]
Eshell V5.2.3.3 (abort with ^G)
1> snmp:c("SAMPLE-MIB", [{db, mnesia}]).
{ok,"./SAMPLE-MIB.bin"}
Result is binary file SAMPLE-MIB.bin.
Continuing the previous erl session:
2> snmp:config().
Simple SNMP configuration tool (v3.0)
----------------------------------------------
Note: Non-trivial configurations still has to be done manually.
IP addresses may be entered as dront.ericsson.se (UNIX only) or 123.12.13.23
1. System name (sysName standard variable) [xxx's agent]sample agent
2. Engine ID (snmpEngineID standard variable)[xxx's engine]sample engine
3. The UDP port the agent listens to. (standard 161) [4000]9161
4. IP address for the agent (only used as id
when sending traps) []127.0.0.1
5. IP address for the manager (only this manager will have access
to the agent, traps are sent to this one) []127.0.0.1
6. To what UDP port at the manager should traps
be sent (standard 162)? [5000]9162
7. What SNMP version should be used (1,2,3,1&2,1&2&3,2&3)? [3]1&2
8. Do you want a none- minimum- or semi-secure configuration?
Note that if you chose v1 or v2, you won't get any security for these
requests (none, minimum, semi) [minimum]
9. Where is the configuration directory (absolute)? [/usr/home/xxx/otp-snmp]
10. Current configuration files will now be overwritten. Ok [y]/n?y
------------------------
Info: 1. SecurityName "initial" has noAuthNoPriv read access and authenticated write access to the "restricted" subtree.
2. SecurityName "all-rights" has noAuthNoPriv read/write access to the "internet" subtree.
3. Standard traps are sent to the manager.
4. Community "public" is mapped to security name "initial".
5. Community "all-rights" is mapped to security name "all-rights".
The following files were written: agent.conf, community.conf,
standard.conf, target_addr.conf, target_params.conf,
notify.conf vacm.conf, sys.config
------------------------
ok
Result is the following files: agent.conf, community.conf, context.conf, notify.conf, standard.conf, sys.config, target_addr.conf, target_params.conf, vacm.conf.
3> snmp:mib_to_hrl("SAMPLE-MIB").
"SAMPLE-MIB.hrl" written.
ok
Result is file SAMPLE-MIB.hrl.
mkdir /tmp/db
Here is a tiny Erlang module with functions to create the table in Mnesia, get and set values in the table, and start the snmp agent.
Here is the transcript of an Erlang shell session starting things up:
erl -mnesia dir '"/tmp/db"' -config ./sys -name sample
(sample@xyz.com)1> c(snmp_sample).
{ok,snmp_sample}
(sample@xyz.com)2> mnesia:create_schema([node()]).
ok
(sample@xyz.com)3> mnesia:start().
ok
(sample@xyz.com)4> snmp_sample:create_table().
{atomic,ok}
(sample@xyz.com)5> snmp_sample:set_counts("srv01",3,44).
ok
(sample@xyz.com)6> snmp_sample:get_counts().
[[{serverTable,"srv01",3,44}]]
(sample@xyz.com)7> snmp_sample:init_snmp().
<0.140.0>
(sample@xyz.com)8> snmp_mgr:g([[1,3,6,1,2,1,1,1,0]]).
ok
* Got PDU: v1, CommunityName = "public"
Response, Request Id:112362370
(sample@xyz.com)9> snmp_mgr:gn([[1,3,6,1,4,1,99999,1]]).
ok
* Got PDU: v1, CommunityName = "public"
Response, Request Id:38817076
[name,5,115,114,118,48,49] = "srv01"
(sample@xyz.com)10>
Here is an example of a Bourne shell script reading and setting counter values.
First, the script:
# snmpops.sh # Point MIBDIRS at directory containing the MIB for this example. MIBDIRS=+/home/xxx/otp-snmp MIBS=+SAMPLE-MIB export MIBDIRS MIBS snmpwalk -Ob -Cc -v 1 -c public localhost:9161 \ .iso.org.dod.internet.private.enterprises.bazmatic snmpget -Os -v 1 -c public localhost:9161 \ .iso.org.dod.internet.private.enterprises.bazmatic.serverTable.serverEntry.callsIn.5.115.114.118.48.49 snmpset -Os -v 1 -c all-rights localhost:9161 \ .iso.org.dod.internet.private.enterprises.bazmatic.serverTable.serverEntry.callsIn.5.115.114.118.48.49 = 22 snmpget -Os -v 1 -c public localhost:9161 \ .iso.org.dod.internet.private.enterprises.bazmatic.serverTable.serverEntry.callsIn.5.115.114.118.48.49
Then, the results:
SAMPLE-MIB::name.5.115.114.118.48.49 = STRING: "srv01" SAMPLE-MIB::callsIn.5.115.114.118.48.49 = INTEGER: 3 SAMPLE-MIB::callsOut.5.115.114.118.48.49 = INTEGER: 44 callsIn."srv01" = INTEGER: 3 callsIn."srv01" = INTEGER: 22 callsIn."srv01" = INTEGER: 22
revised Jul 22, 2003 - Hal Snyder & Josh Snyder