用于接收snmp警报的python多处理
我希望我的代码能够接收SNMP警报。我正在使用python的用于接收snmp警报的python多处理,python,queue,multiprocessing,snmp,pysnmp,Python,Queue,Multiprocessing,Snmp,Pysnmp,我希望我的代码能够接收SNMP警报。我正在使用python的pysnmp模块。我正在为陷阱侦听器创建一个新进程。我正在使用多处理模块。陷阱侦听器接收snmp警报消息并将其发送到我的主进程,主进程将对它们进行一些计算。但如何将消息数据传递给父进程?我想创建一个队列。但是由于snmp数据是由函数cbFun()接收的,我不知道如何将其传递给trapreciver()。简单的返回函数不起作用 我想我可以使队列成为一个全局变量。这是个好主意吗 我的另一种选择是在cbFun中写入文件,然后在我的主进程中从中
pysnmp
模块。我正在为陷阱侦听器创建一个新进程。我正在使用多处理
模块。陷阱侦听器接收snmp警报消息并将其发送到我的主进程,主进程将对它们进行一些计算。但如何将消息数据传递给父进程?我想创建一个队列。但是由于snmp数据是由函数cbFun()
接收的,我不知道如何将其传递给trapreciver()
。简单的返回函数不起作用
我想我可以使队列成为一个全局变量。这是个好主意吗
我的另一种选择是在cbFun
中写入文件,然后在我的主进程中从中读取
最好的方法是什么
当我执行下面给出的代码时,子进程正在打印收到的snmp消息,但我无法从父进程打印它。我做错了什么
from pysnmp.entity import engine, config
from pysnmp.carrier.asynsock.dgram import udp, udp6
from pysnmp.entity.rfc3413 import ntfrcv
from multiprocessing import Process
import Queue
q = Queue.Queue()
def trapListener():
# Create SNMP engine with autogenernated engineID and pre-bound
# to socket transport dispatcher
snmpEngine = engine.SnmpEngine()
# Transport setup
# UDP over IPv4
config.addSocketTransport(
snmpEngine,
udp.domainName,
udp.UdpTransport().openServerMode(('10.94.175.171', 162))
)
# SNMPv1/2c setup
# SecurityName <-> CommunityName mapping
config.addV1System(snmpEngine,'my-area', 'public')
# Register SNMP Application at the SNMP engine
ntfrcv.NotificationReceiver(snmpEngine, cbFun)
snmpEngine.transportDispatcher.jobStarted(1) # this job would never finish
# Run I/O dispatcher which would receive queries and send confirmations
try:
snmpEngine.transportDispatcher.runDispatcher()
except:
snmpEngine.transportDispatcher.closeDispatcher()
raise
# Callback function for receiving notifications
def cbFun(snmpEngine,stateReference,
contextEngineId, contextName,
varBinds,
cbCtx):
(transportDomain, transportAddress ) = snmpEngine.msgAndPduDsp.getTransportInfo(stateReference)
f=open('eventDescriptions.txt','r')
print('Notification from %s, ContextEngineId "%s", ContextName "%s"' % (
transportAddress, contextEngineId.prettyPrint(),
contextName.prettyPrint()))
for name, val in varBinds:
if name.prettyPrint()=="1.3.6.1.4.1.674.10892.5.3.1.2.0":
print('child: %s' % (val.prettyPrint()))
q.put(val.prettyPrint())
if __name__=="__main__":
p=Process(target=trapListener, args=(child_conn,))
p.start()
print "parent: ", q.get()
p.join()
来自pysnmp.entity导入引擎,配置
从pysnmp.carrier.asynsock.dgram导入udp、udp6
从pysnmp.entity.rfc3413导入ntfrcv
从多处理导入进程
导入队列
q=队列。队列()
def trapListener():
#使用自动生成的engineID和预绑定创建SNMP引擎
#到套接字传输调度器
snmpEngine=engine.snmpEngine()
#传输设置
#IPv4上的UDP
config.addSocketTransport(
snmpEngine,
udp.domainName,
udp.udptTransport().openServerMode(('10.94.175.171',162))
)
#SNMPv1/2c设置
#SecurityName社区名称映射
config.addv1系统(snmpEngine、'my-area'、'public')
#在SNMP引擎上注册SNMP应用程序
ntfrcv.通知接收器(snmpEngine、cbFun)
snmpEngine.transportDispatcher.jobStarted(1)#此作业永远不会完成
#运行I/O调度程序,它将接收查询并发送确认
尝试:
snmpEngine.transportDispatcher.runDispatcher()
除:
snmpEngine.transportDispatcher.closeDispatcher()
提升
#用于接收通知的回调函数
def cbFun(snmpEngine、stateReference、,
contextEngineId,contextName,
瓦宾德,
cbCtx):
(transportDomain,transportAddress)=snmpEngine.msgandpudsp.getTransportInfo(stateReference)
f=打开('eventDescriptions.txt','r')
打印('来自%s、ContextEngineId“%s”、ContextName“%s”的通知%(
transportAddress,contextEngineId.prettyPrint(),
contextName.prettyPrint())
varBinds中的val作为名称:
如果name.prettyPrint()=“1.3.6.1.4.1.674.10892.5.3.1.2.0”:
打印('子项:%s'(val.prettyPrint()))
q、 put(val.prettyPrint())
如果名称=“\uuuuu main\uuuuuuuu”:
p=进程(target=trapListener,args=(子连接)
p、 开始()
打印“父项:”,q.get()
p、 加入
我不确定,但使用子流程模块可能会更简单。
您可以使用subprocess.Popen创建一个新流程,然后使用communicate方法向该流程发送数据。您可以尝试使用闭包将队列对象传递给cbFun。大概是这样的:
def getCbFun(queue): # closure
def cbFun(snmpEngine,stateReference,
contextEngineId, contextName,
varBinds,
cbCtx):
...
queue.add(varBinds)
...
return cbFun
...
# Shared queue object
queue = Queue()
# Register SNMP Application at the SNMP engine
ntfrcv.NotificationReceiver(snmpEngine, getCbFun(queue))
...
因此,如果cbFun()将使用getCbFun()的局部作用域中的队列对象,那么它不是全局的。我认为
子流程
主要用于在shell中运行非python代码或命令。但是,我尝试了一下,将trapreciver()
放在一个单独的文件中并运行它。它不起作用。子进程在不等待接收陷阱的情况下退出。我让代码正常工作。我在trapreciver
中创建了cbFun
嵌套函数。队列变量被设置为主进程的本地变量,并传递给trapreciver(q)
。我还打算添加Lock
,这样父进程和子进程的输出就不会混淆。我意识到我的问题是处理变量范围。现在,我在trapreciver
中创建了cbFun
嵌套函数,解决了我认为的问题。这是个好主意吗?代码目前正在运行。但是如果我面临更多的问题,我一定会尝试你的解决方案。谢谢谢谢你的提示。我在代码的其他地方使用了它,在那里我遇到了类似的情况。它工作得很好。