<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:clearspace="http://www.jivesoftware.com/xmlns/clearspace/rss" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Support and Services Partners : Process monitoring with Zenoss  : Comments</title>
    <link>http://community.zenoss.org/docs/DOC-3537#comments</link>
    <description>Comments on : Process monitoring with Zenoss</description>
    <language>en</language>
    <pubDate>Sun, 29 Apr 2012 16:55:10 GMT</pubDate>
    <generator>Jive SBS 4.5.6.2  (http://jivesoftware.com/products/clearspace/)</generator>
    <dc:date>2012-04-29T16:55:10Z</dc:date>
    <dc:language>en</dc:language>
    <item>
      <title>RE: Process monitoring with Zenoss</title>
      <link>http://community.zenoss.org/docs/DOC-3537#comments-5562</link>
      <description>&lt;!-- [DocumentBodyStart:02e11915-5b30-4c58-b5ac-8006d5eb6383] --&gt;&lt;div class="jive-rendered-content"&gt;&lt;p&gt;I have been asked some excellent questions by someone who duplicated the work to use the net-snmp agent to monitor failed processes and to send traps when a process was "unhealthy" (basically pages 7-11 of the paper).&amp;#160; On top of that, he had used the Zenoss trap configuration and event transforms to restart a failed process (pages 29-35).&amp;#160; He found that the event transform on page 31 wasn't working:&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;"I kept getting the following error in zenhub.log:"&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;2012-04-20 14:13:42,525 WARNING zen.Events: Error processing&lt;/p&gt;&lt;p&gt;transform/mapping on Event Class&lt;/p&gt;&lt;p&gt;/App/Stop/instances/1.3.6.1.4.1.1234.123&lt;/p&gt;&lt;p&gt;Problem on line 6: AttributeError: Event instance has no attribute 'errorFlag'&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160; if evt.errorFlag==1:&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;Transform:&lt;/p&gt;&lt;p&gt;&amp;#160; 0 for attr in dir(evt):&lt;/p&gt;&lt;p&gt;&amp;#160; 1&amp;#160;&amp;#160;&amp;#160;&amp;#160; if attr.startswith('1.3.6.1.4.1.2021.2.1.100'):&lt;/p&gt;&lt;p&gt;&amp;#160; 2&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; evt.index=attr.replace('1.3.6.1.4.1.2021.2.1.100.','')&lt;/p&gt;&lt;p&gt;&amp;#160; 3&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; evt.process_name=getattr(evt,'1.3.6.1.4.1.2021.2.1.2.'+evt.index)&lt;/p&gt;&lt;p&gt;&amp;#160; 4&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; evt.errorFlag=getattr(evt,'1.3.6.1.4.1.2021.2.1.100.'+evt.index)&lt;/p&gt;&lt;p&gt;&amp;#160; 5&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; evt.errFixCmd=getattr(evt,'1.3.6.1.4.1.2021.2.1.103.'+evt.index)&lt;/p&gt;&lt;p&gt;&amp;#160; 6&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if evt.errorFlag==1:&lt;/p&gt;&lt;p&gt;&amp;#160; 7&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; evt.summary=evt.process_name + ' process is unhealthy'&lt;/p&gt;&lt;p&gt;&amp;#160; 8&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; evt.severity=5&lt;/p&gt;&lt;p&gt;&amp;#160; 9&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if evt.errorFlag==0:&lt;/p&gt;&lt;p&gt; 10&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; evt.summary=evt.process_name + ' process is healthy'&lt;/p&gt;&lt;p&gt; 11&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; evt.severity=0&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;Well, for starters, I guess I have learned a bit about Python in the last two years so each of those getattr statements in lines 4,5 and 6 should have defaults.&amp;#160; In particular on line 4, the error flag is defined by the net-snmp agent to be 0 if the process is not in error and 1 if it is in error; so a default on the getattr of 2 would not affect the logic of the net-snmp agent but would mean that the test of evt.errorFlag on lines 6 and 9, won't fail if, for some reason there was no attribute 1.3.6.1.4.1.2021.2.1.100.&amp;#160; So lines 3-5 would be better as:&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&amp;#160; 3&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; evt.process_name=getattr(evt,'1.3.6.1.4.1.2021.2.1.2.'+evt.index, 'No process name')&lt;/p&gt;&lt;p&gt;&amp;#160; 4&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; evt.errorFlag=getattr(evt,'1.3.6.1.4.1.2021.2.1.100.'+evt.index,2)&lt;/p&gt;&lt;p&gt;&amp;#160; 5&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; evt.errFixCmd=getattr(evt,'1.3.6.1.4.1.2021.2.1.103.'+evt.index, 'No fix cmd')&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;Still doesn't explain why the attributes were not matching as he assures me that the attributes were actually present.&amp;#160; The only thing I can suggest here are typos - especially watching for the end dot on the getattr statements.&amp;#160; Alternatively, if he had loaded up the SMI or UCD MIBs then this could have resulted in the non-match - see the rest of the discussion.&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;However, more interestingly, he goes on to say:&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;"I checked the event details, and the attributes are definitely there.&lt;/p&gt;&lt;p&gt;I even imported the UCD mib and tried both the transform version&lt;/p&gt;&lt;p&gt;above, and the same one but with named OIDs (eg: prErrorFlag, prNames&lt;/p&gt;&lt;p&gt;etc) as per the UCD mib, but I kept getting the same error.&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;In the end, I wrote the following transform myself which does seem to&lt;/p&gt;&lt;p&gt;work (it includes the extra code to use snmpset to restart the&lt;/p&gt;&lt;p&gt;'unhealthy' process):&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;import os&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;index = getattr(evt,'prIndex','0')&lt;/p&gt;&lt;p&gt;process_name = getattr(evt,'prNames')&lt;/p&gt;&lt;p&gt;errorFlag = getattr(evt,'prErrorFlag')&lt;/p&gt;&lt;p&gt;errFixCmd = getattr(evt,'prErrFixCmd')&lt;/p&gt;&lt;p&gt;if errorFlag==1:&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160; shellcmd = '/usr/bin/snmpset -v 3 -u zenoss -l authPriv -a MD5 -A&lt;/p&gt;&lt;p&gt;zenoss12 -x DES -X zenoss12 ' + dev.manageIp + '&lt;/p&gt;&lt;p&gt;1.3.6.1.4.1.2021.2.1.102.' + str(index) + ' i 1'&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160; os.system(shellcmd)&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160; evt.summary = process_name + ' process is unhealthy'&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160; evt.severity = 5&lt;/p&gt;&lt;p&gt;if errorFlag==0:&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160; evt.summary = process_name + ' process is healthy'&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160; evt.severity = 0&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;Now the comment about importing the UCD mib is interesting.&amp;#160; I did not discuss this much in the paper.&amp;#160; Personally I dislike the way Zenoss uses imported MIBs to "decode" traps (I also hate the fact that there isn't a MIB Browser built in to the product to help you setup OIDs to poll for in performance templates, but that is a different issue).&amp;#160; I think the OID translation stuff in TRAPs is dangerous, especially if you then use transforms to process the trap varbinds.&amp;#160; &lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;My original transform uses OIDs to check for particular trap varbinds.&amp;#160; I had no MIBs imported into Zenoss.&amp;#160; If someone imports the SNMPv2-SMI mib, suddenly all my transform will fail because the code that interprets traps will try to convert oids to names - even partially - so my trap varbinds will suddenly become things like:&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;enterprises.2021.2.1.100&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; instead of&amp;#160;&amp;#160;&amp;#160; 1.3.6.1.4.1.2021.2.1.100&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;The leading 1.3.6.1.4.1 gets translated to enterprises because the SMI (Structure of Management Information) MIB will provide that translation. &lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;When my friend above imported the UCD MIB, the varbinds get translated right down to the trap description name so:&lt;/p&gt;&lt;p&gt;1.3.6.1.4.1.2021.2.1.100.1&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; becomes simply prErrorFlag.1&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;Again, if I had written my transform to match enterprises.2021.2.1.100 then it would break again as the varbind name has changed again.&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;My friend has then obviously made an excellent observation and asks a very pertinent question:&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;I noticed that the event details showed both an indexed and&lt;/p&gt;&lt;p&gt;non-indexed attribute for each attribute which were always the&lt;/p&gt;&lt;p&gt;same.....eg: there was a prErrorFlag and a prErrorFlag.2 both of which&lt;/p&gt;&lt;p&gt;were set to 1 when the process being monitored died. It was using the&lt;/p&gt;&lt;p&gt;non-indexed value that led me to the above script. Is there any reason&lt;/p&gt;&lt;p&gt;I shouldn't be doing it this way? Is there a reason you explicitly use&lt;/p&gt;&lt;p&gt;the indexed values?&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;He's right!&amp;#160; The TRAP itself provides an indexed set of values where the index represents the row of the process table.&amp;#160; So if your snmpd.conf has 3 processes then the first will be index 1, the second index 2 and so on.&amp;#160; Why, with the UCD MIB imported, do we get TWO copies of all the varbinds, one indexed and one non-indexed and which should you use?&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;You need to look in $ZENHOME/Products/ZenEvent/zentrap.py for the answer.&amp;#160; The function oid2name is what actually does the conversion of oids to textual names (note that this website may have messed up the Python indentation):&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; def oid2name(self, oid, exactMatch=True, strip=False):&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; """&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Returns a MIB name based on an OID and special handling flags.&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; @param oid: SNMP Object IDentifier&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; @type oid: string&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; @param exactMatch: find the full OID or don't match&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; @type exactMatch: boolean&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; @param strip: show what matched, or matched + numeric OID remainder&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; @type strip: boolean&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; @return: Twisted deferred object&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; @rtype: Twisted deferred object&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; """&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if type(oid) == type(()):&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; oid = '.'.join(map(str, oid))&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; oid = oid.strip('.')&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if exactMatch:&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if oid in self.oidMap:&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return self.oidMap[oid]&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else:&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return oid&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; oidlist = oid.split('.')&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; for i in range(len(oidlist), 0, -1):&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; name = self.oidMap.get('.'.join(oidlist[:i]), None)&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if name is None:&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; continue&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; oid_trail = oidlist[i:]&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if len(oid_trail) &amp;gt; 0 and not strip:&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return "%s.%s" % (name, '.'.join(oid_trail))&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else:&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return name&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return oid&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;Note the test almost at&amp;#160; the end of "if len(oid_trail) &amp;gt; 0 and not strip" - strip is a boolean parameter passed to this function.&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;Now look further down zentrap.py to the asyncHandleTrap function which is what actually constructs the trap.&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; # Decode all variable bindings. Allow partial matches and strip&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; # off any index values.&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; for vb_oid, vb_value in variables:&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; vb_value = self._convert_value(vb_value)&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; vb_oid = '.'.join(map(str, vb_oid))&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; # Add a detail for the variable binding.&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; r = self.oid2name(vb_oid, exactMatch=False, strip=False)&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; result[r] = vb_value&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; # Add a detail for the index-stripped variable binding.&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; r = self.oid2name(vb_oid, exactMatch=False, strip=True)&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; result[r] = vb_value&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160; This is around line 485 in my Core 3.1 version.&amp;#160; oid2name is called first with strip=False and then with a strip=True.&amp;#160; So two event attributes are created out of 1 varbind - one with the instance included and one with the instance stripped off.&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;If there was always just one instance to process then we could forget about all this clever code to work out the instance.&amp;#160; With these particular traps from the process table, you probably are safe using either the simple attribute or the indexed one.&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;However, go and look at the transform supplied as standard for /Net/Link/snmp_linkDown.&amp;#160; It has some code that does something vaguely similar to the transforms discussed here:&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;if_index_str = getattr(evt.details, "ifIndex", None) &lt;/p&gt;&lt;p&gt;if if_index_str is not None and device is not None: &lt;/p&gt;&lt;p&gt;&amp;#160; if_index = int(if_index_str) &lt;/p&gt;&lt;p&gt;&amp;#160; for interface in device.os.interfaces(): &lt;/p&gt;&lt;p&gt;&amp;#160; if interface.ifindex == if_index: &lt;/p&gt;&lt;p&gt;&amp;#160; evt.component = interface.id &lt;/p&gt;&lt;p&gt;&amp;#160; break&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;And look at the screenshot of a real captured event:&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&lt;a href="http://community.zenoss.org/servlet/JiveServlet/showImage/105-5562-11990/net_link_down_snmptrap.jpg"&gt;&lt;img alt="net_link_down_snmptrap.jpg" class="jive-image" height="264" src="http://community.zenoss.org/servlet/JiveServlet/downloadImage/105-5562-11990/450-264/net_link_down_snmptrap.jpg" width="450"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;This is a trap to do with interfaces and there are multiple instances of interfaces - ifIndex.1 and ifIndex.65539.&amp;#160; Again the simple attribute ifIndex also exists and, I assume, has taken the last value.&amp;#160; I think this demonstrates that, depending on the trap and the varbinds it sends, you cannot always rely on using the "uninstanced" attribute.&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;The last question asked is about "good news" traps from the net-snmp agent.&lt;/p&gt;&lt;p&gt;"&lt;/p&gt;&lt;p&gt;I have my /etc/snmpd/snmpd.conf file on the monitored device&lt;/p&gt;&lt;p&gt;configured exactly as you have done on pages 9,10 of your paper. You&lt;/p&gt;&lt;p&gt;mention on page 9 and 10 about not using the following line in the&lt;/p&gt;&lt;p&gt;monitored device's /etc/snmpd/snmpd.conf file:&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;monitor -u _internal -r 20 -S -e procFix "Process table event" prErrorFlag !=0&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;....because zenoss doesn't get to see the 'good news' SNMP trap. Well,&lt;/p&gt;&lt;p&gt;I don't have this line in my snmpd.conf, but I am not getting the good&lt;/p&gt;&lt;p&gt;news event. My version of the transform definitely works....the bad&lt;/p&gt;&lt;p&gt;news event is received by zenoss, the snmpset command is run back to&lt;/p&gt;&lt;p&gt;the monitored device, and the process which died is restarted.....at&lt;/p&gt;&lt;p&gt;this point I would expect a good news event to be sent to zenoss, but&lt;/p&gt;&lt;p&gt;it never happens....the snmpd on the monitored device never generates&lt;/p&gt;&lt;p&gt;the good news trap. Before I had a working transform, if I manually&lt;/p&gt;&lt;p&gt;did a process restart, it did send the good news trap. So it seems&lt;/p&gt;&lt;p&gt;that the snmpset command is somehow causing snmpd to not generate the&lt;/p&gt;&lt;p&gt;good news trap."&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;I have to agree here.&amp;#160; I also do not get the good news trap when the transform automation has done the snmpset.&amp;#160; The prErrFixCmd DOES run; the problem IS resolved.&amp;#160; But in the next polling interval specified in your snmpd.conf I also do not get a "good news" trap issued, whereas if I restart a failed process manually then I DO see a "good news" trap.&amp;#160; Fortunately, it doesn't affect the ability to raise subsequent "bad news" traps but I too would want to see the good news confirmation.&amp;#160; Incidentally, I had the polling interval on my monitor statement originally set to 10 (seconds) and I tried upping that to 60 - but still no good news!&amp;#160; By turning the debugging up to "Debug" on the zentrap daemon, one can see that the "good news" trap never arrives, so the problem must be with the agent.&amp;#160; Be interesting to see if other people with different versions of the agen get different results&amp;#160; - these latest tests are with net-snmp-5.4.1-19.6 on an Open SuSE platform.&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;Cheers,&lt;/p&gt;&lt;p&gt;Jane&lt;/p&gt;&lt;/div&gt;&lt;!-- [DocumentBodyEnd:02e11915-5b30-4c58-b5ac-8006d5eb6383] --&gt;</description>
      <pubDate>Sun, 29 Apr 2012 15:57:24 GMT</pubDate>
      <author>community@zenoss.org</author>
      <guid>http://community.zenoss.org/docs/DOC-3537#comments-5562</guid>
      <dc:date>2012-04-29T15:57:24Z</dc:date>
      <clearspace:dateToText>1 year, 10 months ago</clearspace:dateToText>
      <clearspace:objectType>0</clearspace:objectType>
    </item>
  </channel>
</rss>

