我正在尝试编写一个可以嵌入到我的 python 应用程序中的 python SNMP 代理,以便 OpenNMS 可以远程监控该应用程序。OpenNMS 期望 Agent 实现HOST-RESOURCES-MIB
查询两个字段 hrSWRunName
和hrSWRunStatus
.
我以一个 pysnmp 示例作为我的代码的基础,并在我认为必要的时候对其进行了编辑。生成的代码如下所示:
import logging
from pysnmp import debug
from pysnmp.carrier.asyncore.dgram import udp
from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413 import cmdrsp, context
from pysnmp.proto.api import v2c
from pysnmp.smi import builder, instrum, exval
# debug.setLogger(debug.Debug('all'))
formatting = '[%(asctime)s-%(levelname)s]-(%(module)s) %(message)s'
logging.basicConfig(level=logging.DEBUG, format=formatting, )
logging.info("Starting....")
# Create SNMP engine
snmpEngine = engine.SnmpEngine()
# Transport setup
# UDP over IPv4
config.addTransport(
snmpEngine,
udp.domainName,
udp.UdpTransport().openServerMode(('localhost', 12345))
)
# SNMPv2c setup
# SecurityName <-> CommunityName mapping.
config.addV1System(snmpEngine, 'my-area', 'public')
# Allow read MIB access for this user / securityModels at VACM
config.addVacmUser(snmpEngine,
2,
'my-area',
'noAuthNoPriv',
(1, 3, 6, 1, 2, 1),
(1, 3, 6, 1, 2, 1))
# Create an SNMP context
snmpContext = context.SnmpContext(snmpEngine)
logging.debug('Loading HOST-RESOURCES-MIB module...'),
mibBuilder = builder.MibBuilder().loadModules('HOST-RESOURCES-MIB')
logging.debug('done')
logging.debug('Building MIB tree...'),
mibInstrum = instrum.MibInstrumController(mibBuilder)
logging.debug('done')
logging.debug('Building table entry index from human-friendly representation...')
# see http://www.oidview.com/mibs/0/HOST-RESOURCES-MIB.html
hostRunTable, = mibBuilder.importSymbols('HOST-RESOURCES-MIB', 'hrSWRunEntry')
instanceId = hostRunTable.getInstIdFromIndices(1)
logging.debug('done')
# The following shows the OID name mapping
#
# hrSWRunTable 1.3.6.1.2.1.25.4.2 <TABLE>
# hrSWRunEntry 1.3.6.1.2.1.25.4.2.1 <SEQUENCE>
# hrSWRunIndex 1.3.6.1.2.1.25.4.2.1.1 <Integer32>
# hrSWRunName 1.3.6.1.2.1.25.4.2.1.2 <InternationalDisplayString> 64 Char
# hrSWRunID 1.3.6.1.2.1.25.4.2.1.3 <ProductID>
# hrSWRunPath 1.3.6.1.2.1.25.4.2.1.4 <InternationalDisplayString> 128 octets
# hrSWRunParameters 1.3.6.1.2.1.25.4.2.1.5 <InternationalDisplayString> 128 octets
# hrSWRunType 1.3.6.1.2.1.25.4.2.1.6 <INTEGER>
# hrSWRunStatus 1.3.6.1.2.1.25.4.2.1.7 <INTEGER> <<===== This is the key variable used by Opennms
# http://docs.opennms.org/opennms/releases/18.0.1/guide-admin/guide-admin.html#_hostresourceswrunmonitor)
logging.debug('Create/update HOST-RESOURCES-MIB::hrSWRunTable table row:')
varBinds = mibInstrum.writeVars((
(hostRunTable.name + (1,) + instanceId, 1),
(hostRunTable.name + (2,) + instanceId, 'AppName'), # <=== Must match OpenNMS service-name variable
(hostRunTable.name + (3,) + instanceId, {0,0}), #
(hostRunTable.name + (4,) + instanceId, 'All is well'),
(hostRunTable.name + (5,) + instanceId, 'If this was not the case it would say so here'),
(hostRunTable.name + (6,) + instanceId, 4),# Values are ==> unknown(1), operatingSystem(2), deviceDriver(3), application(4)
(hostRunTable.name + (7,) + instanceId, 1) #<<=== This is the status number OpenNMS looks at Values are ==> running(1), runnable(2), notRunnable(3), invalid(4)
))
for oid, val in varBinds:
print('%s = %s' % ('.'.join([str(x) for x in oid]), val.prettyPrint()))
logging.debug('done')
logging.debug('Read whole MIB (table walk)')
oid, val = (), None
while True:
oid, val = mibInstrum.readNextVars(((oid, val),))[0]
if exval.endOfMib.isSameTypeWith(val):
break
print('%s = %s' % ('.'.join([str(x) for x in oid]), val.prettyPrint()))
logging.debug('done')
# logging.debug('Unloading MIB modules...'),
# mibBuilder.unloadModules()
# logging.debug('done')
# --- end of table population ---
# Register SNMP Applications at the SNMP engine for particular SNMP context
cmdrsp.GetCommandResponder(snmpEngine, snmpContext)
cmdrsp.SetCommandResponder(snmpEngine, snmpContext)
cmdrsp.NextCommandResponder(snmpEngine, snmpContext)
cmdrsp.BulkCommandResponder(snmpEngine, snmpContext)
# Register an imaginary never-ending job to keep I/O dispatcher running forever
snmpEngine.transportDispatcher.jobStarted(1)
# Run I/O dispatcher which would receive queries and send responses
try:
snmpEngine.transportDispatcher.runDispatcher()
except:
snmpEngine.transportDispatcher.closeDispatcher()
raise
代码运行不会产生错误。varBinds 和 MIB Table walk 显示了我认为我应该期待的:
[2016-12-29 16:42:49,323-INFO]-(SNMPAgent) Starting....
[2016-12-29 16:42:49,470-DEBUG]-(SNMPAgent) Loading HOST-RESOURCES-MIB module...
[2016-12-29 16:42:49,631-DEBUG]-(SNMPAgent) done
[2016-12-29 16:42:49,631-DEBUG]-(SNMPAgent) Building MIB tree...
[2016-12-29 16:42:49,631-DEBUG]-(SNMPAgent) done
[2016-12-29 16:42:49,631-DEBUG]-(SNMPAgent) Building table entry index from human-friendly representation...
[2016-12-29 16:42:49,631-DEBUG]-(SNMPAgent) done
[2016-12-29 16:42:49,632-DEBUG]-(SNMPAgent) Create/update HOST-RESOURCES-MIB::hrSWRunTable table row:
1.3.6.1.2.1.25.4.2.1.1.1 = 1
[2016-12-29 16:42:49,651-DEBUG]-(SNMPAgent) done
1.3.6.1.2.1.25.4.2.1.2.1 = TradeLoader
1.3.6.1.2.1.25.4.2.1.3.1 = 0
1.3.6.1.2.1.25.4.2.1.4.1 = All is well
1.3.6.1.2.1.25.4.2.1.5.1 = If this was not the case it would say so here
1.3.6.1.2.1.25.4.2.1.6.1 = 'application'
1.3.6.1.2.1.25.4.2.1.7.1 = 'running'
[2016-12-29 16:42:49,651-DEBUG]-(SNMPAgent) Read whole MIB (table walk)
1.3.6.1.2.1.25.4.2.1.1.1 = 1
1.3.6.1.2.1.25.4.2.1.2.1 = TradeLoader
1.3.6.1.2.1.25.4.2.1.3.1 = 0
1.3.6.1.2.1.25.4.2.1.4.1 = All is well
1.3.6.1.2.1.25.4.2.1.5.1 = If this was not the case it would say so here
1.3.6.1.2.1.25.4.2.1.6.1 = 'application'
1.3.6.1.2.1.25.4.2.1.7.1 = 'running'
1.3.6.1.2.1.25.5.1.1.1.1 = <no value>
1.3.6.1.2.1.25.5.1.1.2.1 = <no value>
[2016-12-29 16:42:53,490-DEBUG]-(SNMPAgent) done
最后,调度程序启动。
问题是当我尝试查询代理时没有任何反应。我没有得到回应。我查看了我的代码,其中一件显而易见的事情是我没有将 snmpEngine 显式链接到我创建的 MIB。我应该这样做吗?
任何见解都会受到极大的欢迎,因为我目前正在努力了解该去哪里。