2013-09-28 91 views
1

我想在沒有阻塞的情況下在python中做snmpget。我不想使用線程,我非常喜歡gevent庫,但我之前沒有使用它,所以不知道從哪裏開始。我看着他們的例子,並瞭解我如何可以猴子補丁插座。如果我修補套接字並使用像pysnmp這樣的模塊,那麼執行非阻塞查詢就足夠了嗎?gevent和snmp在Python中

此外,由於我將在linux上運行,因此我可以使用snmpget命令行實用程序,因此我可以使用gevent.subprocess調用它們,該版本在1.0版本中提供,可以使這些查詢非阻塞。

我寧願使用python模塊來執行snmp get比使用命令行實用程序,但如果第二個選項更容易工作,那麼我不會介意採取這種方法。

任何提示/方向將不勝感激。謝謝!

UPDATE:

我已經採取了pysnmp_eventlet模塊,並試圖採取與eventlet的扭曲的例子。我不確定爲什麼我的回調函數沒有被調用。我可以看到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 
) 

回答

1

在上面的代碼中,你仍然需要運行調度的eventlet處理傳入的數據包:

while True: 
    eventlet.sleep(dispatcher.getTimerResolution()) 
    try: 
     dispatcher.handleTimerTick(time.time()) 
    except Exception: 
     print 'Error while handling dispatcher tick!' 
     raise 

你通常會在greenlet中產卵並忘記它(或者可能實現一些有序關閉)。

(我會在將來某個時候可以加入適量的例子給pysnmp_eventlet。)

+0

添加一些示例會很棒 - 我可以幫助您解決問題,一旦我獲得了項目中的基礎知識。 – opensourcegeek

+0

您的補丁現在是否已合併到pysnmp中繼中?沒有任何可以在Google上找到的合併版本的文檔 –

+0

恐怕不是,這似乎已經以某種方式從todo列表中刪除了。它不應該太難,只需要花時間。 – flub

1

有一個補丁pysnmp,使得它與eventlet運行:

https://bitbucket.org/flub/pysnmp_eventlet

+0

能否請您總結一下該鏈接的內容的情況下,它會在未來走404? –

+0

準備好生產使用了嗎? – opensourcegeek

+0

是的,我們在python 2.7上使用它進行生產。對於其他Python版本,您可能需要等到合併到pysnmp中。 – flub