vincentbernat / snimpy

interactive SNMP tool with Python
http://snimpy.readthedocs.org/
185 stars 44 forks source link

Question: How do I lookup values across two tables #77

Closed gavmckee80 closed 6 years ago

gavmckee80 commented 6 years ago

Hi,

Would it be possible to provide an example were I do efficent indexing across tables

I want to pull values for interfaces from both the ifTable

for idx in m.ifDescr:
    if m.ifDescr[idx] == "lo":
        continue
    if m.ifOperStatus[idx] != "up":
        continue
    print("{} {}".format(m.ifName[idx],
                            m.ifHCInOctets[idx],
                            ))

And from EtherLike-MIB

for idx in m.dot3StatsTable:
    print m.dot3StatsFCSErrors[idx], m.dot3StatsDuplexStatus[idx]

I'd have to lookup the EtherLike-MIB index in the IFMIB.ifTable for the interface name

Is there an efficient approach to this ?

vincentbernat commented 6 years ago

Since both tables use the same index, you only have to walk one:

for idx in m.ifDescr:
   print(m.ifName[idx], m.dot3StatsFCSErrors[idx])
gavmckee80 commented 6 years ago
In [69]: for idx in m.ifDescr:
    ...:    print(m.ifName[idx], m.dot3StatsFCSErrors[idx])
    ...:
---------------------------------------------------------------------------
SNMPNoSuchInstance                        Traceback (most recent call last)
<ipython-input-69-ef67b7dfd542> in <module>()
      1 for idx in m.ifDescr:
----> 2    print(m.ifName[idx], m.dot3StatsFCSErrors[idx])
      3

Looks like this throws an exception

If I walk the EtherLike table on its own

In [70]: for idx in m.dot3StatsTable: ...: print m.dot3StatsFCSErrors[idx], m.dot3StatsDuplexStatus[idx] ...: 0 fullDuplex(3) 0 fullDuplex(3) 0 fullDuplex(3)

vincentbernat commented 6 years ago

Just catch the exception and continue the loop. Or walk m.dot3StatsTable instead of m.ifDescr.

for idx in m.dot3StatsTable:
    print m.dot3StatsFCSErrors[idx], m.dot3StatsDuplexStatus[idx], m.ifName[idx]
gavmckee80 commented 6 years ago

Thanks @vincentbernat

gavmckee80 commented 6 years ago

@vincentbernat - a final quick question I'm building a document to submit to elastic / influx or any other backend DB

In [150]:
     ...: for idx in m.ifDescr:
     ...:     try:
     ...:         if m.ifAdminStatus[idx] == "up" and m.ifOperStatus[idx] == "up":
     ...:             ifHCInOctets = m.ifHCInOctets[idx]
     ...:             ifHCOutOctets = m.ifHCOutOctets[idx]
     ...:             ifHCInMulticastPkts = m.ifHCInMulticastPkts[idx]
     ...:             ifLastChange = m.ifLastChange[idx]
     ...:
     ...:             {'measurement': '<measurement_name>',
     ...:             'tags':{'hostname':'<hostname>','interface':m.ifName[idx]},
     ...:             'fields':{
     ...:             }
     ...:             }
     ...:             print {'test':ifHCInOctets}
     ...:             #print("{} {} {} {} {}".format(m.ifName[idx],m.ifAlias[idx],m.ifHCInOctets[idx],m.dot3StatsFCSErrors[idx],m.ifLastChange[idx]))
     ...:     except Exception as e:
     ...:         print e
     ...:         #print m.ifName[idx], m.ifHCInOctets[idx], m.ifLastChange[idx]
     ...:
{'test': <Unsigned64: 5520318006>}
{'test': <Unsigned64: 757231301>}
{'test': <Unsigned64: 726847832>}
{'test': <Unsigned64: 1040544110>}

How do i get the value instead of the Unsigned64 object being added to the dict?

vincentbernat commented 6 years ago

The Unsigned64 type should behave just like an int. However, you can coerce it as int with int(ifHCInOctets).

cbueche commented 6 years ago

A little bit related to your issue: not all interface tables indexed by idx are the same length or contain values for each idx, this is why you sometimes get exceptions. So you may want to check InterfaceAPI / get() in https://github.com/cbueche/Agent-Jones/blob/master/aj/aj.py I collect all tables (descr, name, status, etc) independently using bulk-get, and then join them together starting at line 727.

Not an example of good coding, but the idea works well.

gavmckee80 commented 6 years ago

thanks @vincentbernat @cbueche - thanks for sharing , this is a very interesting approach. Most open source projects (telegraf) are really hard to scale. I want to collect data from around 1500 devices , mostly Cisco N3K, some 5K/7K, Arista and L1 switches.

cbueche commented 6 years ago

Agent-Jones works since 2-3 years for a network service provider, with mostly Cisco IOS and XE. Nexus isn't really tested, especially redundant-connected fabric extenders are problematic (most likely in every NMS anyway). Please note Agent-Jones is built for device identification/inventory a few times per day, and not for rapid interface polling. This would be better done using some async.