[英]gevent and snmp in python
我想在python中做一个snmpget而不阻塞。 我不想使用线程,我真的很喜欢gevent库,但是我以前没有使用过它,所以不确定从哪里开始。 我查看了他们的示例,并了解了如何使用猴子补丁插槽。 如果我猴子修补套接字并使用pysnmp这样的模块,执行非阻塞查询就足够了吗?
另外,由于我将在Linux机器上,所以我可以访问snmpget
命令行实用程序,因此我可以使用gevent.subprocess来调用它们,该版本在1.0版中可用,这也可以使这些查询成为非阻塞形式。
与使用命令行实用程序相比,我更喜欢使用python模块进行snmp获取,但是,如果第二个选项更易于使用,则我不介意采用这种方法。
任何提示/方向将不胜感激。 谢谢!
更新:
我采用了pysnmp_eventlet模块,并尝试采用带eventlet的Twisted示例。 我不确定为什么我的回调函数没有被调用。 我可以在tcpdump中看到SNMP请求和响应。 但是我的回调函数(cbFun)没有被调用。 我想念什么吗?
from pysnmp_eventlet.carrier.eventlet.dispatch import EventletDispatcher
from pysnmp_eventlet.carrier.eventlet.dgram import udp
from pysnmp.entity.rfc3413 import cmdgen
from pysnmp.entity import engine, config
# Create SNMP engine instance
snmpEngine = engine.SnmpEngine()
dispatcher = EventletDispatcher()
snmpEngine.registerTransportDispatcher(dispatcher)
# SecurityName <-> CommunityName mapping
config.addV1System(snmpEngine, 'my-area', 'public')
# Specify security settings per SecurityName (SNMPv1 - 0, SNMPv2c - 1)
config.addTargetParams(snmpEngine, 'my-creds', 'my-area', 'noAuthNoPriv', 1)
# UDP/IPv4
config.addSocketTransport(
snmpEngine,
udp.domainName,
udp.UdpEventletTransport().openClientMode()
)
config.addTargetAddr(
snmpEngine,
'my-router',
udp.domainName,
('127.0.0.1', 161),
'my-creds',
timeout=300, # in 1/100 sec
retryCount=1
)
def cbFun(cbCtx):
(errorIndication, errorStatus, errorIndex, varBinds) = cbCtx
if errorIndication:
print(errorIndication)
elif errorStatus:
print('%s at %s' % (
errorStatus.prettyPrint(),
errorIndex and varBinds[int(errorIndex)-1][0] or '?'
)
)
else:
for oid, val in varBinds:
print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))
cmdGen = cmdgen.GetCommandGenerator()
cmdGen.sendReq(
snmpEngine,
'my-router',
( ('1.3.6.1.2.1.1.1.0', None), ),
cbFun
)
pysnmp的一个补丁可以使它与eventlet一起运行:
在上面的代码中,您仍然需要运行eventlet的调度程序来处理传入的数据包:
while True:
eventlet.sleep(dispatcher.getTimerResolution())
try:
dispatcher.handleTimerTick(time.time())
except Exception:
print 'Error while handling dispatcher tick!'
raise
通常,您会在一个greenlet中生成它,然后将其忽略(或者可能对其执行一些有序的关闭)。
(我将来会在pysnmp_eventlet中添加适当的示例。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.