在单个事务中查询多个OID时如何调查Pysnmp中每个oid的errorStatus

时间:2019-01-22 22:33:41

标签: python-3.x pysnmp

我正在尝试在单个getCMD命令中查询多个OID。我正在寻找一种检查errorIndication和errorStatus响应的最佳方法。我能够做到这一点的一种方法是创建一个字典并对其进行迭代,如下所示:

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都返回errorStatus,则我的else子句下不会打印任何内容,并且elif errorStatus:

下的两个OID都将输出相同的errorStatus

如何重写我的elif errorStatus子句以仅输出失败的OID的oid和errorStatus,并仍然在else下打印成功的oid查询

1 个答案:

答案 0 :(得分:1)

单个error-status字段的这种奇异性是SNMP v1的缺点之一。因此,如果必须使用SNMP v1,则绝对没有解决方案。

在SNMP v2c +中,不建议使用单个error-status字段,而推荐使用所谓的exception objects。想法是返回一些标记值以响应,以指示所请求的任何受管对象实例存在问题,而不仅仅是其中一个。

使用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来说,唯一可能的例外是“ mib-view结束”。