在单个事务中查询多个 OID 时,如何调查 Pysnmp 中每个 oid 的错误状态

How to investigate errorStatus for each oid in Pysnmp when querying multiple OID's in a single transaction

我正在尝试在单个 getCMD 命令中查询多个 OID。我正在寻找检查每个 errorIndication 的响应的最佳方法,errorStatus.One 我能够实现此目的的方法是创建一个字典并对其进行迭代,如下所示:

startTime2 = datetime.now()
print(' From Dict '.center(100, '#'))

mibs_2_pull = {'sysDescr': ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)),
               'sysName': ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysName', 0))
}

for mib in mibs_2_pull:
    errorIndication, errorStatus, errorIndex, varBinds = next(
    getCmd(SnmpEngine(), credentials, target,cd, mibs_2_pull[mib] ))
    if errorIndication:
        print(errorIndication)
    elif errorStatus:
        print('%s at %s' % (errorStatus.prettyPrint(),
                            errorIndex and varBinds[int(errorIndex) - 1][0] or '?'))
    else:
        for varBind in varBinds:
            print(' = '.join([x.prettyPrint() for x in varBind]))
print(datetime.now() - startTime2)

这很好用,因为我可以单独处理每个 oid 的 errorIndication 和 errorStatus,但是,这种方法比将所有 OID 拉到一个 getCMD 中要慢:

errorIndication, errorStatus, errorIndex, varBinds = next(
    getCmd(se,
           credentials,
           target,
           cd,
           ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysName', 1)),
           ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)),
           ))
if errorIndication:
    # Invalid Credentials
    # IP not reachable

    print('errorIndication:', errorIndication)
elif errorStatus:
    # Invalid OID

    for x in varBinds:
        print(x[1].prettyPrint())
    # for an_oid, a_val in varBinds:
        # print(an_oid), a_val

        #errorStatus_string = 'errorStatus: ' + '%s at %s' % (errorStatus.prettyPrint(),
        #                                                     errorIndex and varBinds[int(errorIndex) - 1][0] or '?')
        # print(errorStatus_string)

        # return the errorStatus of a Single OID
        #   errorStatus_string = 'errorStatus: ' + '%s at %s' % (errorStatus.prettyPrint(),
        #                       errorIndex and varBinds[int(errorIndex) - 1][0] or '?')
        #   print(errorStatus_string)
        # #Determine how to check the error status for each OID individually

else:
    # Will Only Execute if everything is successful
    for an_oid, a_val in varBinds:
        print(an_oid, a_val, sep=' => ')

print (datetime.now() - startTime1)

上面的代码片段要快得多,但是,我不确定如何分别访问我查询过的每个 OID 的 errorStatus。坦率地说,这可能是由于我对某些 Python 基础知识缺乏了解。如果我的 OID 中的任何一个 returns 出现 errorStatus,则在我的 else 子句下不会打印任何内容,并且将为 elif errorStatus:

下的两个 OID 打印相同的 errorStatus

如何重写我的 elif errorStatus 子句以仅打印我失败的 OID 的 oid 和 errorStatus,并且仍然在 else

下打印我成功的 oid 查询

单个 error-status 字段的这种奇异性是 SNMP v1 的缺点之一。所以如果非要用SNMP v1,那是绝对没有办法的。

在 SNMP v2c+ 中,这个 error-status 字段已弃用,取而代之的是所谓的 exception objects。这个想法是 return 一些标记值来响应以指示所请求的任何托管对象实例存在问题,而不仅仅是其中一个。

使用 pysnmp,您的代码可能如下所示:

for oid, value in varBinds:
    if value.isSameTypeWith(NoSuchInstance()) or value.isSameTypeWith(NoSuchObject()):
        print('managed object %s does not exist at this agent' % (oid,))
        continue
     ...

请记住,这些“异常对象”只能用于响应 GET 或 SET 命令,对于 GETNEXT,唯一可能的异常是“end-of-mib-view”。