我对芹菜的记录器有问题。我有一个渲染帧的函数。我记录了我生成的子进程的输出,但似乎只写入了每个工作线程从队列中选取的第一个作业。队列中的所有后续任务都不会生成日志文件。我也尝试使用python自己的日志记录,但发生了同样的问题。是否有我可能缺少的配置?
@task(queue='rndr')
def rndr(params):
path = get_logger_path(params)
logger = rndr.get_logger(logfile=path)
return render(params, logger)
我以这种方式定义我的任务,因为我的重试记录器的定义会有所不同,即 rndr_retry.get_logger...
我的芹菜配置如下所示:
BROKER_HOST = "xxx.xxx.xxx.xxx"
BROKER_PORT = 5672
BROKER_USER = "xxxx"
BROKER_PASSWORD = "xxxx"
CELERY_RESULT_BACKEND = 'amqp'
CELERY_DISABLE_RATE_LIMITS = True
CELERY_ACKS_LATE = True
CELERY_IMPORTS = ['lib.tasks.concatenate', 'lib.tasks.encode', 'lib.tasks.render', 'lib.tasks.still_image', 'lib.tasks.retry']
CELERY_ROUTES = {'lib.tasks.encode':{'queue': 'encode'},
'lib.tasks.concatenate':{'queue': 'encode'},
'lib.tasks.still_image':{'queue': 'encode'},
'lib.tasks.render':{'queue':'rndr'},
'lib.tasks.retry':{'queue': 'retry'}
}
希望有人能阐明为什么只有队列中的第一个任务会写......
提前谢谢你。
更新:根据要求,这里是渲染方法的部分版本,没有所有细节......
def render(params, logger):
#load params to local values
try:
#create subprocess
output = child_proc.communicate()[0]
logger.info('output')
logger.info(output)
ret = child_proc.wait()
if ret not in [0,1]:
raise Exception('subprocess failed')
except Exception, exc:
logger.info(' '.join(str(x) for x in exc.args))
#mark as failed...
return
return
我应该补充一点,该文件不仅不会在后续任务中写入,甚至不会创建日志文件。
经过一些试验,我注意到没有创建传递的日志文件。我添加了一个方法来确保文件在传递给 get_logger() 之前存在。还是没有运气。由于我的大多数任务都运行子进程,因此我决定采用更简单的方法,并拥有一个打开的文件对象,并将其传递给 stdout 和 stderr 中的子进程调用,并在适当的情况下关闭文件对象。无论我运行多少任务,这似乎都有效。我应该注意每个任务写入一个唯一的文件。
Anyhoo,我想我会写信给芹菜开发人员并将其标记为错误。我在开发论坛的某个地方读到,芹菜的伐木器需要一些爱。
干杯。
更新:
在与芹菜开发人员交谈后,得出的结论是,伐木器不适合以这种方式使用。为任务启动日志记录实例,但重复的任务不会记录。我最终只是简单地写入一个文件来规避日志记录模块的问题。可以解决问题,并且不会引起任何冲突,因为每个渲染任务都使用唯一的文件。