Making a Mnesia Table SNMP Accessible

Contents

  1. Introduction
  2. Define a Mnesia Table
  3. Create the MIB File
  4. Create the .funcs File
  5. Compile the MIB for OTP
  6. Create sys.config and .conf Files
  7. Create MIB Header for Mnesia
  8. Create Data Directory for Mnesia
  9. Create Erlang Program
  10. Start OTP with Mnesia and SNMP agent
  11. Access the Table from net-snmp
  12. References

Introduction

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.


Define a Mnesia Table

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:

serverTable.hrl.


Create the MIB File

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.

SAMPLE-MIB.mib.


Create the .funcs File

Since default mnesia functions are used, this step could probably be omitted if RowStatus were used.

SAMPLE-MIB.funcs.


Compile the MIB for OTP

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.


Create sys.config and .conf Files

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.


Create MIB Header for Mnesia

3> snmp:mib_to_hrl("SAMPLE-MIB").
"SAMPLE-MIB.hrl" written.
ok

Result is file SAMPLE-MIB.hrl.


Create Data Directory for Mnesia

Will use non-volatile storage (disc_copies) for convenience. Designate a directory on disk where the table will be stored.
mkdir /tmp/db


Create Erlang Program

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.

snmp_sample.erl.


Start OTP with Mnesia and 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> 

Access the Table from net-snmp

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

References

  1. Application for Private Enterprise Number
  2. Erlang/OTP SNMP User's Guide See Chapter 6 - Implementation Example
  3. Standard Names for Versions of the SNMP Protocol

revised Jul 22, 2003 - Hal Snyder & Josh Snyder