Create a Custom Resource Type

This section describes how to create a custom resource type to collect SNMP data from tables with arbitrary indexes. Whether it is an MIB-2 host-resources storage table, a Brocade fibre channel port table, or the existing node-level performance data and interface resource types, Horizon uses the custom resource type to collect and display the data.

Create a resourceType definition

Configure data collection as normal, but with a few small differences. First, make sure a resourceType element exists in datacollection-config.xml to specify the custom resource type. This element needs to be before the "groups" element. For the MIB-2 host resources storage table, we have an entry like this:

<resourceType name="hrStorageIndex" label="Storage (MIB-2 Host Resources)">
  <persistenceSelectorStrategy class="org.opennms.netmgt.collectd.PersistAllSelectorStrategy"/>
  <storageStrategy class="org.opennms.netmgt.dao.support.IndexStorageStrategy"/>
</resourceType>

Name attribute

The name attribute ("hrStorageIndex" above) is not magical in any way; it does not need to correlate to an MIB that OpenNMS has knowledge of. The datacollection-config.xml file and the snmp-graph.properties file use this attribute to refer to this custom resource type.

To ensure all resource type data stays separate, all RRD data goes into a directory based on this name. For example, for node 1, all data for the example resource type goes into ${OPENNMS_HOME}/share/rrd/snmp/1/hrStorageIndex.

The length of the index does not matter; this facility should work to collect from multiply indexed tables such as tcpConnTable.

Label attribute

The label attribute ("Storage (MIB-2 Host Resources)" above) provides a user-friendly label in the webUI when listing this resource type.

Storage strategy classes

The persistenceSelectorStrategy and storageStrategy define the classes used to decide whether data for this resource type should be persisted (written to disk), and how the data is written to disk. The classes in the example above are the usual ones, but for more flexibility, you can use SiblingColumnStorageStrategy or PersistRegexSelectorStrategy.

Create "group" and "mibObj" definitions

Create the "group" and its children "mibObj" elements as you normally would, but with two differences:

  • Set the ifType attribute for the group element to be "all". Without this, the data will be incorrectly assumed to be node-level data (not indexed).

  • Set the instance attribute on the mibObj elements to be the name of your resource type. This would be "hrStorageIndex" for the example above.

Here is the data to collect for the hrStorageIndex resource type:

<group name="mib2-host-resources-storage" ifType="all">
  <mibObj oid=".1.3.6.1.2.1.25.2.3.1.3" instance="hrStorageIndex" alias="hrStorageDescr" type="string" />
  <mibObj oid=".1.3.6.1.2.1.25.2.3.1.4" instance="hrStorageIndex" alias="hrStorageAllocUnits" type="gauge" />
  <mibObj oid=".1.3.6.1.2.1.25.2.3.1.5" instance="hrStorageIndex" alias="hrStorageSize" type="gauge" />
  <mibObj oid=".1.3.6.1.2.1.25.2.3.1.6" instance="hrStorageIndex" alias="hrStorageUsed" type="gauge" />
</group>

Add the group to a system definition

In datacollection-config.xml, OpenNMS needs to be able to map a remote SNMP agent’s system object ID to a set of data collection groups so it knows what it should gather for different types of SNMP agents.

You must add the newly created collection group to one or more system definitions (systemDef) in datacollection-config.xml so that OpenNMS will try to collect data for that collection group.

The following shows that the group for "mib2-host-resources-storage" was added to the definition for Net-SNMP which matches any agent that has a system object ID that begins with .1.3.6.1.4.8072.3.:

<systemDef name="Net-SNMP">
  <sysoidMask>.1.3.6.1.4.1.8072.3.</sysoidMask>
  <collect>
    <includeGroup>mib2-host-resources-storage</includeGroup>
    <includeGroup>mib2-host-resources-system</includeGroup>
    <includeGroup>mib2-host-resources-memory</includeGroup>
    <includeGroup>net-snmp-disk</includeGroup>
    <includeGroup>ucd-loadavg</includeGroup>
    <includeGroup>ucd-memory</includeGroup>
    <includeGroup>ucd-sysstat</includeGroup>
  </collect>
</systemDef>

Create a report in snmp-graph.properties

Finally, you create a report in snmp-graph.properties like you normally would, with the exception that you set the type to match the name of the resource type.

Here is an example for hrStorageIndex disk utilization data:

report.mib2.storage.usage.name=Storage Utilization (MIB-2 Host Resources)
report.mib2.storage.usage.columns=hrStorageSize, hrStorageUsed, hrStorageAllocUnits
report.mib2.storage.usage.type=hrStorageIndex
report.mib2.storage.usage.command=--title="Storage Utilization" \
   --vertical-label="Bytes" \
   DEF:total={rrd1}:hrStorageSize:AVERAGE \
   DEF:used={rrd2}:hrStorageUsed:AVERAGE \
   DEF:units={rrd3}:hrStorageAllocUnits:AVERAGE \
   CDEF:totalBytes=total,units,* \
   CDEF:usedBytes=total,used,-,units,* \
   LINE2:totalBytes#0000ff:"Total" \
   GPRINT:totalBytes:AVERAGE:" Avg  \\: %8.2lf %s" \
   GPRINT:totalBytes:MIN:"Min  \\: %8.2lf %s" \
   GPRINT:totalBytes:MAX:"Max  \\: %8.2lf %s\\n" \
   AREA:usedBytes#ff0000:"Used " \
   GPRINT:usedBytes:AVERAGE:" Avg  \\: %8.2lf %s" \
   GPRINT:usedBytes:MIN:"Min  \\: %8.2lf %s" \
   GPRINT:usedBytes:MAX:"Max  \\: %8.2lf %s\\n"

Make sure that you add your new report to the reports parameter in the same file, otherwise the graphing system will not add it as an available report. For the above example, the report name is "mib2.storage.usage".

reports=mib2.bits, mib2.percentdiscards, mib2.percenterrors, \
...
mib2.storage.usage, \
...