You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Celery的task_prerun中获取任务签名与参数名值对?

问题

需要记录所有Celery任务请求及其接收的参数,当前使用以下代码实现日志功能:

@task_prerun.connect()
def log_celery_args(task, **kwargs):
    logger.info(f"{task.name} {kwargs['kwargs']}", extra=kwargs['kwargs'])

但该方案在任务函数使用非命名参数时失效:虽然能从kwargs['args']获取参数值,但无法在日志extra中保持{参数名: 值}的格式。

已尝试的操作:

  • 打印task和task.request的所有参数查找相关信息;
  • 发现signature函数但仅用于修改签名;
  • 尝试使用celery.app.trace模块实现带参数名的日志记录。
解决方案

可以通过Python的inspect模块获取任务函数的参数签名,将位置参数(args)和关键字参数(kwargs)合并成带参数名的字典,具体实现如下:

import inspect
from celery.signals import task_prerun

@task_prerun.connect()
def log_celery_args(task, **kwargs):
    # 获取任务函数的参数签名
    sig = inspect.signature(task.run)
    # 绑定位置参数和关键字参数到签名
    bound_args = sig.bind(*kwargs['args'], **kwargs['kwargs'])
    bound_args.apply_defaults()  # 填充默认参数
    # 得到包含所有参数名和值的字典
    full_args = bound_args.arguments
    
    # 记录日志,extra使用带参数名的字典
    logger.info(f"{task.name} {full_args}", extra=full_args)

说明

  • task.run是Celery任务实际执行的函数,通过inspect.signature获取它的参数定义;
  • sig.bind()会把位置参数按顺序映射到对应的参数名,自动处理位置参数和关键字参数的合并;
  • apply_defaults()会自动填充函数定义中的默认参数值,确保日志记录完整;
  • 最终full_args就是{参数名: 参数值}格式的字典,完美适配日志extra的需求。

内容的提问来源于stack exchange,提问作者Dany Y

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 12:10:22