python多处理接收snmp警报

标签 python queue multiprocessing snmp pysnmp

我希望我的代码能够接收 SNMP 警报。我正在使用 python 的 pysnmp 模块。我正在为陷阱监听器创建一个新进程。我正在使用多处理模块。陷阱监听器接收 snmp 警报消息并将其发送到我的主进程,该进程将对它们进行一些计算。但是我如何将该消息数据传递给我的父进程呢?我想创建一个队列。但由于 snmp 数据是由函数 cbFun() 接收的,我不知道如何将其传递给 trapReceiver()。简单的返回函数是行不通的。

我想我可以让队列成为一个全局变量。这是个好主意吗?

我的另一个选择是写入 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()

最佳答案

您可以尝试使用闭包将 Queue 对象传递给 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() 本地范围内的队列对象(该范围不是全局的)。

关于python多处理接收snmp警报,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22065495/

相关文章:

python - 使用 cffi 加载 .so 库

python - 新的 wxpython 控件在调整大小之前不会显示

arrays - 基于数组与基于列表的堆栈和队列

java - 为什么我们可以实例化堆栈而不是队列?

python - 使用多处理修改全局变量

Python多进程记录到共享文件

python - 正则表达式 Python

python - Matplotlib 无处不在地绘制未定义的图

javascript - queue.js 是如何工作的?

python-3.x - 我应该如何设置 spaCy 服务器来处理多个并发请求(非阻塞)?