在单个事务中查询多个 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”。
我正在尝试在单个 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:
如何重写我的 elif errorStatus
子句以仅打印我失败的 OID 的 oid 和 errorStatus,并且仍然在 else
单个 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”。