Я всегда нахожусь в войне между максимальной скоростью и минимальным потреблением ресурсов, поэтому моя цель — найти наилучшее сочетание скорости и потребления ресурсов.
Для каждого устройства snmp я хотел бы сканировать oids под несколькими ветками.
В каждой ветке есть динамическое количество oids, поэтому я не знаю, какие именно oids мне нужны, я просто знаю, что мне нужны все oids в ветке.
У меня есть некоторые устройства, которые поддерживают только SNMPv1, поэтому для этих устройств я написать код, совместимый с SNMPv1.
Для остальных устройств я использую SNMPv2.
SNMPv1
Допустим, у меня есть два OID, которые я хотел бы пройти по их branch('1.3.6.1.2.1.4' and '1.3.6.1.2.1.6')
.
Под OID ветки я подразумеваю все OID в ветке.
У меня есть следующий код:
cmdGen = cmdgen.AsynCommandGenerator()
cmdGen.asyncNextCmd(
cmdgen.CommunityData('public', mpModel=1),
cmdgen.UdpTransportTarget(('192.168.0.101', 161)),
(str('1.3.6.1.2.1.4'),str('1.3.6.1.2.1.6'),),
(__cbFun_Walk, (cmdgen.CommunityData('public', mpModel=1), cmdgen.UdpTransportTarget(('192.168.0.101', 161)))))
cmdGen.snmpEngine.transportDispatcher.runDispatcher()
Это работает хорошо, но единственная проблема заключается в том, что я могу остановить все обходы сразу, поэтому я не могу остановить каждый обход по отдельности, поэтому все обходы завершатся после окончания самого длинного обхода.
Очевидно, это неэффективно.
Я мог бы также написать 2 asyncNextCmd
для OID ветки:
cmdGen = cmdgen.AsynCommandGenerator()
cmdGen.asyncNextCmd(
cmdgen.CommunityData('public', mpModel=1),
cmdgen.UdpTransportTarget(('192.168.0.101', 161)),
(str('1.3.6.1.2.1.4'),),
(__cbFun_Walk, (cmdgen.CommunityData('public', mpModel=1),
cmdgen.UdpTransportTarget(('192.168.0.101', 161)))))
cmdGen.asyncNextCmd(
cmdgen.CommunityData('public', mpModel=1),
cmdgen.UdpTransportTarget(('192.168.0.101', 161)),
(str('1.3.6.1.2.1.6'),),
(__cbFun_Walk, (cmdgen.CommunityData('public', mpModel=1),
cmdgen.UdpTransportTarget(('192.168.0.101', 161)))))
cmdGen.snmpEngine.transportDispatcher.runDispatcher()
Я не слишком хорошо знаю SNMP, но предполагаю, что второй код имеет некоторые недостатки.
Например, на некоторых клиентах у меня есть сотни SNMP-устройств, поэтому я открыл asyncCmd
для каждого сетевого устройства одновременно.
Это привело к большому количеству не отвечающих устройств и слишком высокой загрузке ЦП.
SNMPv2
Я также хотел бы попытаться понять, как работает объем и могу ли я использовать его, чтобы сделать мой код более эффективным.
Допустим, у меня есть 2 ветки, которые я хотел бы пройти.
1.3.6.1.2.1. 4.20 с 5 oids и 1.3.6.1.2.1.4.21 с 39 oids.
Я получаю все значения в обеих ветвях, но я также получаю больше значений, чем мне нужно.
Количество значений, которые я get всегда является ветвью с наибольшим количеством oids, умноженным на количество ветвей, которые у меня есть.
Например, ветка с наибольшим количеством oids имеет 39 oids, а количество ветвей равно 2, поэтому 39*2=78, это означает, что getBulk вернет 78 oids.
Я хочу, чтобы getBulk возвращал все oids ветвей для каждой ветки и ничего больше, поэтому в моем случае я хочу 44 oids (39+5 = 44).
Это мой код:
cmdGen = cmdgen.CommandGenerator()
errorIndication, errorStatus, errorIndex, varBindTable = cmdGen.bulkCmd(
cmdgen.CommunityData('public'),
cmdgen.UdpTransportTarget(('192.168.0.101', 161)),
0, 1,
'1.3.6.1.2.1.4.21', '1.3.6.1.2.1.4.20'
)
if errorIndication:
print errorIndication
elif errorStatus:
print '%s at %s\n' % (
errorStatus.prettyPrint(),
errorIndex and varBindTable[-1][int(errorIndex)-1] or '?'
)
else:
for varBindTableRow in varBindTable:
for name, val in varBindTableRow:
print str(name.prettyPrint()) + ' = ' + str(val.prettyPrint())
Итак, каков наиболее эффективный способ очистки OID нескольких ветвей как для SNMPv1, так и для SNMPv2?