Чтение SNMP из OID с тремя библиотеками дает разное время выполнения
Я уже пользовалась easysnmp
читать SNMP OID, но я выбрал pysnmp
библиотека сейчас, потому что easysnmp
не поддерживал asyncio
архитектура в Python3.
Рассматриваемая проблема заключается в том, что pysnmp
Слишком медленнее, чем другие библиотеки:
pysnmp:
from pysnmp.hlapi import *
import time
t = time.time()
iterator = getCmd(SnmpEngine(),
CommunityData('public'),
UdpTransportTarget(('192.168.1.120', 161)),
ContextData(),
ObjectType(ObjectIdentity("1.3.6.1.2.1.33.1.2.7.0")))
errorIndication, errorStatus, errorIndex, varBinds = next(iterator)
if errorIndication: # SNMP engine errors
print(errorIndication)
else:
if errorStatus: # SNMP agent errors
print('%s at %s' % (
errorStatus.prettyPrint(),
varBinds[int(errorIndex)-1] if errorIndex else '?'))
else:
for varBind in varBinds: # SNMP response contents
print(' = '.join([x.prettyPrint() for x in varBind]))
print(time.time() - t, 's')
Из:
SNMPv2-SMI::mib-2.33.1.2.7.0 = 21
0.15317177772521973 s
easysnmp
from easysnmp import snmp_get
import time
if __name__ == '__main__':
t = time.time()
response = snmp_get(
'1.3.6.1.2.1.33.1.2.7.0', hostname='192.168.1.120',
community='public', version=1
)
print(response.value)
print(time.time() - t, 's')
Из:
21
0.0063724517822265625 s
gosnmp
func elapsed(what string) func() {
start := time.Now()
fmt.Println("start")
return func() {
fmt.Printf("%s took %v\n", what, time.Since(start))
}
}
func snmpRead() {
g.Default.Target = "192.168.1.120"
err := g.Default.Connect()
if err != nil {
log.Fatalf("Connect() err: %v", err)
}
defer g.Default.Conn.Close()
oids := []string{"1.3.6.1.2.1.33.1.2.7.0"}
result, err2 := g.Default.Get(oids) // Get() accepts up to g.MAX_OIDS
if err2 != nil {
log.Fatalf("Get() err: %v", err2)
}
for i, variable := range result.Variables {
fmt.Printf("%d: oid: %s ", i, variable.Name)
switch variable.Type {
case g.OctetString:
fmt.Printf("string: %s\n", string(variable.Value.([]byte)))
default:
fmt.Printf("number: %d\n", g.ToBigInt(variable.Value))
}
}
}
func main() {
defer elapsed("snmp")()
snmpRead()
}
Из:
start
0: oid: .1.3.6.1.2.1.33.1.2.7.0 number: 21
snmp took 3.668148ms
В 30 раз быстрее чем pysnmp
Мне нужно асинхронное выполнение которого go-routine
населенный asyncio
в Python3.
Итак, означает ли это, что я должен мигрировать из pysnmp
в gosnmp
?
1 ответ
Помните, что первый вызов pysnmp может занять гораздо больше времени по сравнению с последующими вызовами. Из-за отложенного импорта, индексации, возможной компиляции MIB и т. Д.
Поэтому, если ваш вариант использования состоит в том, чтобы выдавать много запросов SNMP от одного и того же процесса, я бы посоветовал принять это во внимание при измерении времени.
Другое дело, что последний (неизданный) pysnmp ввел асинхронные привязки для низкоуровневых подпрограмм SNMP, т.е. исключая механизм SNMP и все тяжелые механизмы, которые он задействует.
pysnmp.hlapi.v1arch.asyncio
API должен быть очень похож на pysnmp.hlapi.v3arch.asyncio
однако с точки зрения подписи он должен быть быстрее за счет отсутствия поддержки SNMPv3. Поддержка MIB все еще на месте, если вам это нужно.
Когда вы импортируете только pysnmp.hlapi.asyncio
, вы эффективно получите pysnmp.hlapi.v3arch.asyncio
так что ладить v1arch
вам нужно импортировать это явно.
Например, приведенный ниже скрипт (работающий под GitHub master pysnmp) может быть быстрее:
import asyncio
from pysnmp.hlapi.v1arch.asyncio import *
@asyncio.coroutine
def run():
snmpDispatcher = SnmpDispatcher()
iterator = getCmd(
snmpDispatcher,
CommunityData('public'),
UdpTransportTarget(('192.168.1.120', 161)),
('1.3.6.1.2.1.33.1.2.7.0', None)
)
errorIndication, errorStatus, errorIndex, varBinds = yield from iterator
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]))
snmpDispatcher.transportDispatcher.closeDispatcher()
asyncio.get_event_loop().run_until_complete(run())