我已经使用easysnmp
读取SNMP OID,但我现在选择了pysnmp
库,因为easysnmp
不支持Python3中的asyncio
archtecture。
考虑的问题是,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
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
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
比pysnmp
快30倍
我需要go-routine
在Python3中填充asyncio
的异步性能。
那么,这是否意味着我应该从pysnmp
迁移到gosnmp
?
请记住,相对于后续调用,第一次pysnmp调用可能需要更多时间。由于惰性导入,索引,可能的MIB编译等。
因此,如果您的用例是从同一进程发出许多SNMP查询,我建议在测量所用时间时考虑到这一点。
另一件事是最新的(未发布的)pysnmp在低级SNMP例程中引入了asyncio绑定,即不包括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())