Re: [tkined] SNMP to SQL

From: Eddie Corns (E.Corns@ed.ac.uk)
Date: Tue Feb 29 2000 - 15:59:08 MET


More on walking multiple devices.

The snippets I posted before that I used for testing the speed of explicit
polling were, if you recall, a) restricted to ifTable entries and b) buggy
because of forgetting about the non-contiguity of the indexes. So I put
together a little test script for doing more generic polls. It does multiple
tables on multiple machines. It looks like this:

package require Tnm 2.1
# usage: parpoll "OID1 OID2 OID3 ..." dev1 dev2 dev3 ...

proc polldev {snc handle OIDl} {
    $snc getnext $OIDl [list procpoll $snc $handle $OIDl %E %V]
}

proc procpoll {snc handle OIDl err args} {
    global sname nxpref
    if {$err != "noError"} {
        puts "$sname($handle) $err"
    } {
        foreach MVAR $args pref $nxpref($handle) {
            set oid [lindex $MVAR 0]
            if {[string match $pref* $oid]} {
                append ops "\n [mib name $oid] [lindex $MVAR 2]"
                lappend myOIDl [lindex $MVAR 0]
                lappend mynx $pref
            }
        }
        if {[info exists mynx]} {
            puts "$sname($handle)::$ops"
            set nxpref($handle) $mynx
            polldev $snc $handle $myOIDl
        }
    }
}
        
set OIDl [lindex $argv 0]
set devl [lrange $argv 1 end]
set smax 1

foreach dev $devl {
    set snconn($smax) [snmp session -address $dev]
    set sname($smax) $dev
    foreach OID $OIDl {lappend nxpref($smax) [mib oid $OID]}
    polldev $snconn($smax) $smax $OIDl
    incr smax
}

snmp wait

for {set sind 1} {$sind < $smax} {incr sind} {
    $snconn($sind) destroy
}

examples:
$ parpoll "sysUpTime ifDescr ifInOctets ifOutOctets ifInErrors" `cat switches`
$ parpoll "ipRouteDest ipRouteNextHop ipRouteMetric1" `cat routers`

It takes first a list of OIDs (which must be a single argument hence the
quotes) and a list of devices to poll (these are separate args). It opens a
connection to each device and then does a GETNEXT for each OID. It continues
doing GETNEXTs for each OID until they return a value beyond the given table.
When all OIDs have been exhausted it stops, the OIDs do not have to generate
tables of the same length, each one just stops returning values at the
appropriate point (so it should handle sparse tables but I'm not sure how to
test it) in fact if you put a few scalars in it will retrieve them once too.
It terminates polling a device if it receives any error. If you get something
like tooBig you need to use less OIDs. It probably ought to handle noSuchName
better as this indicates the end of the MIB but I'm not sure if it might occur
elsewhere?

It's fairly fast both because it is retrieving multiple values on each device
and because it is polling all devices simultaneously. This should also reduce
the CPU on each device since the polls should be fairly evenly distributed.

Using this method should considerably speed up my polling loop even though I'm
going to generate more polls - the extra ones will just get thrown away.

Probably all this is well known to many but may be useful to some. Comments
welcome.

Eddie

--
!! This message is brought to you via the `tkined & scotty' mailing list.
!! Please do not reply to this message to unsubscribe. To subscribe or
!! unsubscribe, send a mail message to <tkined-request@ibr.cs.tu-bs.de>.
!! See http://wwwsnmp.cs.utwente.nl/~schoenw/scotty/ for more information.



This archive was generated by hypermail 2b29 : Mon Jan 08 2001 - 15:27:38 MET