Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何从芹菜中获取发起任务执行的队列_Python_Celery - Fatal编程技术网

Python 如何从芹菜中获取发起任务执行的队列

Python 如何从芹菜中获取发起任务执行的队列,python,celery,Python,Celery,因此,我正在创建一个监视器应用程序,它将从芹菜任务发送日志到麋鹿堆栈 到目前为止,我已经做到了: from project.celery import app def monitor(app): state = app.events.State() def on_event_success(event): state.event(event) task = state.tasks.get(event[

因此,我正在创建一个监视器应用程序,它将从芹菜任务发送日志到麋鹿堆栈

到目前为止,我已经做到了:

from project.celery import app


    def monitor(app):
        state = app.events.State()

        def on_event_success(event):
            state.event(event)

            task = state.tasks.get(event['uuid'])
            if task.name:
                    task_name = task.name
                    task_origin = task.origin
                    task_type = task.type
                    task_worker = task.worker
                    task_info = task.info()
                    task_log = "TASK NAME {}, TASK ORIGIN {}, TASK TYPE {}, TASK WORKER {}, TASK ARGS {}\n\n".format(task_name, task_origin, task_type, task_worker, task_info['args'])
                    print "SUCCESS: {}".format(task_log)

        with app.connection() as connection:
            recv = app.events.Receiver(connection, handlers={
                    'task-succeeded': on_event_success
            })
            recv.capture(limit=None, timeout=None, wakeup=True)

    if __name__ == '__main__':
        application = app
        monitor(app)
使用这段代码,我能够捕获任务中几乎所有可用的信息,但我没有找到一种方法来捕获生成任务执行的队列

我有两个队列:

CELERY_QUEUES = (
    # Persistent task queue
    Queue('celery', routing_key='celery'),
    # Persistent routine task queue
    Queue('routine', routing_key='routine')
)

我想知道是哪个队列发起了我的任务执行,从事件创建的任务对象中获取这些信息

要做到这一点,您需要


您还需要为已发送的
任务
事件实现一个处理程序,就像您对
任务成功
所做的那样

您的监控应用程序应至少保留所有捕获事件的任务id(事件[“uuid”])和路由键(
event[“routing\u key”]
)。在需要路由键信息时,我使用中的TTLCache进行此操作,并在任务成功和任务失败事件处理程序中使用此字典

如果希望以任务名称和参数作为示例,则需要以与上面所述相同的方式处理
task received
事件

您可能想知道为什么我使用TTLCache—我们的芹菜集群每天运行数百万个任务,将所有任务发送的事件数据保存在内存中很快就会占用所有可用内存

最后,以下是缓存任务发送数据并在任务成功事件处理程序中使用该数据的代码:

from cachetools import TTLCache
from project.celery import app


def monitor(app):
    state = app.events.State()

    # keep a couple of days of history in case not acknowledged tasks are retried
    task_info = TTLCache(float('inf'), 3.2 * 24 * 60 * 60)

    def on_event_success(event):
        nonlocal task_info
        state.event(event)

        task = state.tasks.get(event['uuid'])
        if task.name:
                task_name = task.name
                task_origin = task.origin
                task_type = task.type
                task_worker = task.worker
                t_info = task.info()
                task_log = "TASK NAME {}, TASK ORIGIN {}, TASK TYPE {}, TASK WORKER {}, TASK ARGS {}".format(task_name, task_$
                print("SUCCESS: {}".format(task_log))
                if event["uuid"] in task_info:
                    cached_task = task_info[event["uuid"]]
                    if "routing_key" in cached_task:
                        print("    routing_key: {}\n\n".format(cached_task["routing_key"]))

    def on_task_sent(event):
        # task-sent(uuid, name, args, kwargs, retries, eta, expires, queue, exchange,
        # routing_key, root_id, parent_id)
        nonlocal task_info
        if event["uuid"] not in task_info:
            task_info[event["uuid"]] = {"name": event["name"],
                                        "args": event["args"],
                                        "queue": event["queue"],
                                        "routing_key": event["routing_key"]}

    with app.connection() as connection:
        recv = app.events.Receiver(connection, handlers={
                'task-succeeded': on_event_success,
                "task-sent": on_task_sent,
                "*": state.event
        })
    recv.capture(limit=None, timeout=None, wakeup=True)


if __name__ == '__main__':
    application = app
    monitor(app)

我从来没有足够的时间来研究芹菜的芹菜.events.state.state类。我知道它使用LRUCache来缓存一些条目,但我不确定是否可以使用它来代替我在代码中使用的TTLCache…

Hi Dejan,只是检查我是否做了预期的事情:我激活了task sent选项,并且我已经创建了所有需要的处理程序可能(成功、失败、启动、接收、发送)。一旦收到“已发送”事件,则键“路由\ U键”“从我的队列”将显示在任务对象上?我这样问是因为我已启用已发送的任务,并且路由密钥仍被打印为“无”。您还需要为已发送的
任务
事件实现一个处理程序,就像您对
任务成功
所做的那样。任务已发送事件处理程序将获得一个具有路由密钥的事件对象。您将此+任务id存储在字典中,以便在任务成功处理程序中使用它…我已使用我提到的所有内容的工作示例更新了答案…它对我仍然不起作用,但可能与我的芹菜版本有关。我已将芹菜发送事件和芹菜发送事件设置为True,但我的任务已发送dler未收到任何事件信息。我将此答案设置为正确,因为您提供的信息完全有意义。这些配置参数已重命名-芹菜现在使用小写的配置变量名称。