ブロックせずにPythonでsnmpgetを実行したいと思います。私はスレッドを使いたくありません。gevent ライブラリが本当に好きですが、これまで使用したことがないので、どこから始めればよいかわかりません。私は彼らの例を見て、どのようにソケットにパッチを当てることができるかを理解しました。ソケットにパッチを適用して pysnmp のようなモジュールを使用すると、ノンブロッキング クエリを実行するのに十分でしょうか?
また、Linux ボックスをsnmpget
使用するので、コマンド ライン ユーティリティにアクセスできるので、バージョン 1.0 で利用可能な gevent.subprocess を使用してそれらを呼び出すことができます。これにより、これらのクエリもノンブロッキングにすることができます。
コマンド ライン ユーティリティを使用するよりも、python モジュールを使用して snmp get を実行することをお勧めします。
ヒント/指示をいただければ幸いです。ありがとう!
アップデート:
私は pysnmp_eventlet モジュールを使用して、イベントレットで Twisted の例を採用しようとしました。コールバック関数が呼び出されない理由がわかりません。SNMP 要求と応答が tcpdump に戻ってくるのを確認できます。ただし、コールバック関数 (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
)