When you navigate to a particular host, select Modeler Plugins from the left panel, and then select Model Device from the Action menu, the system runs all of the associated modelers. What we need to do is copy and customize an existing modeler plugin from $ZENHOME/Products/DataCollector/plugins/zenoss/snmp
and then add that plugin to our list of plugins that our platform's device class will use.
We'll start with creating a Filesystem
modeler plugin. We'll copy the HRFileSystemMap
plugin and call our plugin AIXFileSystemMap.py
. Using the information in the MIB, we can find the place where it stores the list of file systems.
Table 12.1. Modeler Functions
Name | Required? | Description |
---|---|---|
condition() | N | Returns True or False to indicate whether or not to run the other functions |
preprocess() | N | This will get called before the process() function |
process() | Y | This is the actual function that processes any information retrieved from a query and converts it into a format suitable for updating the device model. |
First, verify that your server's SNMP daemon is functional and that you have the correct SNMP version and credentials. We'll assume that we're using SNMP version 1 and are using the public
community, and that your new host will allow connections from our Zenoss server.
Run the snmpwalk command from the Zenoss monitoring server:
snmpwalk -v1 -c public myaixbox.example.com 1.3.6.1.4.1.2.6.191.1 | head
This produces a lot of output that we've truncated to save patience and space.
SNMPv2-SMI::enterprises.2.6.191.1.1.1.0 = INTEGER: 5 SNMPv2-SMI::enterprises.2.6.191.1.1.2.0 = "" SNMPv2-SMI::enterprises.2.6.191.1.1.3.0 = INTEGER: 2 SNMPv2-SMI::enterprises.2.6.191.1.1.4.0 = Gauge32: 0 SNMPv2-SMI::enterprises.2.6.191.1.1.5.0 = INTEGER: 0 SNMPv2-SMI::enterprises.2.6.191.1.1.6.0 = INTEGER: 2 SNMPv2-SMI::enterprises.2.6.191.1.1.7.0 = STRING: "The current used percentage 93 of the file system /mnt has gon" SNMPv2-SMI::enterprises.2.6.191.1.1.9.0 = INTEGER: 0 SNMPv2-SMI::enterprises.2.6.191.1.1.10.0 = INTEGER: 0 SNMPv2-SMI::enterprises.2.6.191.1.1.11.0 = INTEGER: 0
If you do not see output like that above, nothing else will work. Find the issue and fix it.
The Zenoss community Web site has a ZenPack with a graphical MIB browser that might help for these steps.
Following is a list of some common reasons why snmpwalk may not return any data:
SNMP daemon on the remote system is not running.
SNMP daemon on the remote system has different security credentials than what you are using (for example, version 1 instead of version 2c, wrong community name).
SNMP daemon on the remote system allows connections only from certain IP addresses or IP address ranges, and the Zenoss server does not meet that criteria.
SNMP daemon on the remote allows queries only to certain portions of certain MIBs, and you have specified something not allowed by that policy.
Firewall or firewalls between the Zenoss server and the remote system to not allow UDP or SNMP traffic.
Firewall on the Zenoss server does not allow UDP or SNMP traffic outbound or inbound.
Firewall on the remote system does not allow UDP or SNMP traffic outbound or inbound.
As a first sanity check, try the snmpwalk command on the remote host. For example:
snmpwalk -v1 -c public localhost 1.3.6.1.4.1.2.6.191.1 | head
Multiple modelers for different components of a system can be created, or one huge modeler for everything can be created. Smaller modelers are preferred for maintenance reasons. The following modeler is for the file systems, and would live in the modeler/plugins/
directory of your ZenPack.
Python requires that __init__.py
files be in both the modeler/
and the modeler/plugins/
directories. If they are missing your modeler will not load.
__doc__ = """AIXFileSystemMap This modeler determines the filesystems on the device and updates appropriately. It is up to the monitoring template that must be named 'Filesystems' to collect the actual performance data (eg free/available blocks). """ import re from Products.ZenUtils.Utils import unsigned from Products.DataCollector.plugins.CollectorPlugin import SnmpPlugin, \ GetTableMap from Products.DataCollector.plugins.DataMaps import ObjectMap class AIXFileSystemMap(SnmpPlugin): maptype = "FileSystemMap" compname = "os" relname = "filesystems" modname = "Products.ZenModel.FileSystem" deviceProperties = \ SnmpPlugin.deviceProperties + ('zFileSystemMapIgnoreNames',) # # These column names are for the aixFsTable from the # /usr/samples/snmpd/aixmib.my MIB file located on your AIX hosts. # (It's in the bos.net.tcp.adt fileset.) # columns = { '.1': 'snmpindex', # aixFsIndex '.2': 'storageDevice', # aixFsName '.3': 'mount', # aixFsMountPoint '.4': 'type', # aixFsType '.5': 'totalBlocks', # aixFsSize - a value in MB # # Comment out the following entries to reduce the amount # of stuff that we need to send. They are listed here # for reference and completeness. # # '.6': 'aixFsFree', # '.7': 'aixFsNumINodes', # '.8': 'aixFsUsedInodes', # '.9': 'aixFsStatus', # '.10': 'aixFsExecution', # '.11': 'aixFsResultMsg', } snmpGetTableMaps = ( GetTableMap('aixFsTable', '.1.3.6.1.4.1.2.6.191.6.2.1', columns), ) # # This table is included for reference # aixFsType = { 1: 'jfs', 2: 'jfs2', 3: 'cdrfs', 4: 'procfs', 5: 'cachefs', 6: 'autofs', 7: 'afs', 8: 'dfs', 9: 'nfs', 10: 'nfs3', 11: 'other', } def process(self, device, results, log): """Gather data from the standard AIX snmpd + friends""" log.info('processing %s for device %s', self.name(), device.id) getdata, tabledata = results # # Gather the data using SNMP and just exit if there's an SNMP # issue. If we don't, the filesystem table will get # wiped out. Ouch! # fstable = tabledata.get( "aixFsTable" ) if not fstable: log.warn('No SNMP response from %s for the %s plugin', device.id, self.name() ) log.warn( "Data= %s", getdata ) log.warn( "Columns= %s", self.columns ) return skipfsnames = getattr(device, 'zFileSystemMapIgnoreNames', None) maps = [] rm = self.relMap() for fs in fstable.values(): if not fs.has_key("totalBlocks"): continue # Ignore blank entries if not self.checkColumns(fs, self.columns, log): log.warn( "Data= %s", getdata ) log.warn( "Columns= %s", self.columns ) continue log.debug( "Found %s", fs['mount'] ) # # Ensure that we only check on local disk # NB: it may make sense to report on AFS/DFS volumes.... # fstype = self.aixFsType.get( fs['type'], None) if fstype not in ( 'jfs', 'jfs2' ): continue if fs['totalBlocks'] > 0 and (not skipfsnames or \ not re.search(skipfsnames,fs['mount'])): om = self.objectMap(fs) # # The internal id that Zenoss uses can be used in URLs, # while Unix filesystem names cannot. # Map to an URL-safe name. # om.id = self.prepId(om.mount) # # Map our MIB data to what Zenoss expects # om.blockSize = 1024**2; # ie MB rm.append(om) maps.append(rm) # # As a final sanity check, see if we found anything. If we # didn't find anything, that's probably an error so just return. # if len(maps) == 0: log.warn( "No filesystems found by %s for %s", self.name(), device.id) return return maps
Note
Because this question occurs so often in the mailing lists, the following information bears repeating. The function name required of any modeler is the process()
function.
To test your new modeler plugin, add it to the list of modeler plugins. With the newly created AIX
device class selected, click Details, and then select Modeler Plugins. Add the appropriate plugin from the list, and then click Save.
You can test your new plugin by using zenmodeler from the command line:
zenmodeler run -d myaixbox.example.com -v 10
For testing purposes, you may want to add this and only this modeler plugin to one particular host and make it the only plugin. Any syntax errors or exceptions will be visible so that you can hopefully debug them.
Once you are satisfied that everything is working correctly, verify everything by modeling the device and then navigating to the device overview page. If everything is correct, you'll see your list of file systems, but with unknown
for everything except the total size of the file systems. The actual usage numbers of the file system is collected by a different mechanism -- a performance data collector.
Keep in mind that a modeler is run infrequently (such as once a day or once a week, depending on your settings), while a performance data collector is run every five or ten minutes.