Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SNMP v3 Engine Discovery is slow for 250 Hosts and CPU is taking 90% when trying using asynio #402

Open
ganeshhsbsoft opened this issue May 11, 2021 · 0 comments

Comments

@ganeshhsbsoft
Copy link

Hi,

    For each Host, SNMPEngine object is initialized and it is takes lot of time and CPU due to lot __manageColumns, exportSymbols  activities.

  Is it possible to use one SNMPEngine  object to query all hosts EngineID ? If there other way to query only EngineID from 250+ hosts concurrently ?

Script:

import asyncio
import pysnmp.hlapi.asyncio as snmp
import time
from pysnmp import debug
debug.setLogger(debug.Debug("all", 'dsp', 'msgproc', 'secmod'))

async def get(host, port, user, oid, timeout=5, retries=1):
result = []
try:
snmpEngine = snmp.SnmpEngine()
transportTarget = snmp.UdpTransportTarget((host, port), timeout=timeout, retries= retries)
observerContext = {}
snmpEngine.observer.registerObserver(lambda e, p, v, c: c.update(securityEngineId=v['securityEngineId']), 'rfc3412.prepareDataElements:internal', cbCtx=observerContext)
authData = snmp.UsmUserData(user)

    response = await snmp.getCmd(snmpEngine,
                                 authData,
                                 transportTarget,
                                 snmp.ContextData(),
                                 #snmp.ObjectType(snmp.ObjectIdentity(oid)),
                                 snmp.ObjectType(snmp.ObjectIdentity('1.3.6.1.2.1.1')),
                                 lookupMib=False
                                 )

    errorIndication, errorStatus, errorIndex, varBinds = response

    if errorIndication:                
        print(f'{host}: errorIndication: {errorIndication}')
    elif errorStatus:
        print('{}: {} at {}'.format(host, errorStatus.prettyPrint(), errorIndex and varBinds[int(errorIndex) - 1][0] or '?'))

    if 'securityEngineId' not in observerContext:
        print("Can't discover peer EngineID, errorIndication: %s" % errorIndication)
    else:
        securityEngineId = observerContext.pop('securityEngineId')
        print('Remote securityEngineId = %s' % securityEngineId.prettyPrint())
        result.append(securityEngineId.prettyPrint())

    snmpEngine.transportDispatcher.closeDispatcher()
except Exception as err:
    print (f'Error at SNMP get() due to {err}')
finally:
    print(f'Get {host}, {oid}: {result}')
    return result

async def main():
st = time.time()
tasks = []
tasks.append(get('192.168.50.124', 161, "AUTHPRIV", '1.3.6.1.2.1.1.1.0', 5, 1))
tasks.append(get('192.168.50.124', 161, "AUTHPRIV", '1.3.6.1.2.1.1.1.0', 5, 1))
tasks.append(get('192.168.50.124', 161, "AUTHPRIV", '1.3.6.1.2.1.1.1.0', 5, 1))
tasks.append(get('192.168.50.124', 161, "AUTHPRIV", '1.3.6.1.2.1.1.1.0', 5, 1))
tasks.append(get('192.168.50.124', 161, "AUTHPRIV", '1.3.6.1.2.1.1.1.0', 5, 1))
tasks.append(get('192.168.50.124', 161, "AUTHPRIV", '1.3.6.1.2.1.1.1.0', 5, 1))
tasks.append(get('192.168.50.124', 161, "AUTHPRIV", '1.3.6.1.2.1.1.1.0', 5, 1))
tasks.append(get('192.168.50.124', 161, "AUTHPRIV", '1.3.6.1.2.1.1.1.0', 5, 1))
tasks.append(get('192.168.50.124', 161, "AUTHPRIV", '1.3.6.1.2.1.1.1.0', 5, 1))
tasks.append(get('192.168.50.124', 161, "AUTHPRIV", '1.3.6.1.2.1.1.1.0', 5, 1))
print ("Time taken to append ", time.time() - st)
results = list(filter(lambda a: a, await asyncio.gather(*tasks)))
print(f'main() results: {results}')

print ("Time taken to complete ", time.time() - st, len(results))

if name == 'main':
asyncio.run(main())

Thanks in advance,
Ganesh

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant