芹菜与日志

时间:2015-06-16 16:05:41

标签: python rabbitmq celery

我正在努力整合一个系统,通过RabbitMQ进行日志记录(并最终写入数据库)。我发现Logbook库有一个MessageQueueHandler(和RabbitMQHandler),它将python日志记录写入消息队列。这似乎很有效。但是,当我尝试使用具有关联任务的Celery工作人员消化这些消息时,我收到一条未知消息警告,然后删除该消息而不读取它:

[2015-06-16 15:59:06,688: WARNING/MainProcess] Received and deleted unknown message. Wrong destination?!?

邮件正文的全部内容是:

body: {u'thread_name': u'MainThread', u'extra': {}, u'process': 11784, u'module': u'__main__', u'heavy_init
ialized': True, u'information_pulled': True, u'exception_message': None, u'message': u'test', u'exception_name': None, u'frame_correction': 0, u'filen
ame': u'<input>', u'lineno': 2, u'kwargs': {}, u'msg': u'test', u'channel': u'__main__', u'args': [], u'func_name': u'<module>', u'process_name': u'Ma
inProcess', u'formatted_exception': None, u'thread': 12904, u'level': 2, u'greenlet': 12904, u'time': u'2015-06-16T15:59:06.989000Z'} (502b)
{content_type:u'application/json' content_encoding:u'utf-8'
  delivery_info:{'consumer_tag': u'5', 'redelivered': False, 'routing_key': u'logging', 'delivery_tag': 1, 'exchange': u'logging'} headers={}}

我有两个理由可以想到这种情况正在发生。一个是消息中的json不是Python格式,因此其中包含Null(而不是None)和true(而不是True)。我认为这可能失败的第二个原因是因为消息是通过Logbook发送到交换机(并路由到队列)而不是通过Celery任务(与工作人员相关联)。

有没有办法将这两种技术结合起来,以便Logbook MessageQueueHandler可以写入消息队列,而Celery worker可以从这个队列中读取?

编辑添加: 以下是celery工作程序使用的tasks.py函数,用于从Logbook的RabbitMQHandler类填充的日志记录队列中获取消息:

@shared_task
def digest_logs(logging_queue_data):
    for k,v in logging_queue_data.iteritems():
        print k, v
    completion_indicator = 'Complete'
    return completion_indicator

运行worker的celery命令如下:

celery -A proj.tasks worker --loglevel=debug -Q logging

2 个答案:

答案 0 :(得分:0)

您已将celery配置为侦听日志消息发送到的队列。 Celery希望它们是内部格式的任务消息(即指定要运行的任务)。

解决方案是为芹菜和日志提供单独的队列。我建议使用celery的默认队列 - 即像这样启动worker:

celery -A proj.tasks worker -Q celery

然后您的芹菜任务必须从logging队列中读取 - 您需要使用其中一个可用库(librabbitmqamqp,{{1} } ...)从puka队列中读取日志消息。

答案 1 :(得分:0)

我最后使用Kombu而不是Celery编写了一个工作人员,因为使用Kombu库时,编写消息的代码也不一定是监听消息的代码(换句话说,你没有必须在消息队列的两边都有相同的代码。所以最终没有一个很好的方法来使用Celery。