Пользовательский логгер Django + Djcelery

Я пытаюсь использовать комбинацию пользовательского регистратора Django и задачи Celery для захвата определенных сообщений журнала приложений и асинхронного сброса их в DynamoDB. Я создал задачу Django Celery, которая принимает сообщение журнала и асинхронно передает его в DynamoDB. Я попытался вызвать эту задачу с сельдереем из своего пользовательского регистратора, чтобы асинхронно передать ее в DynamoDB.

Однако пользовательский регистратор Django не позволяет мне импортировать:

from celery.task import task, Task, PeriodicTask, periodic_task

Мой сервер вылетает из-за ошибки ниже:

ValueError: Unable to configure handler 'custom_handler': Cannot resolve 'myApp.analytics.tasks.LogHandler': cannot import name cache

Я знаю, что Django Logger docs предостерегает от циклический импорт, если файл настраиваемого регистратора включает settings.py, но я убедился, что это не так. Но он по-прежнему дает мне ту же ошибку, что и при циклическом импорте.

Я что-то делаю не так или есть другой способ добиться асинхронной передачи данных в DynamoDB с помощью настраиваемого регистратора Django и DjCelery?

Спасибо за любую помощь.


person Taher Saeed    schedule 17.07.2012    source источник
comment
Может быть, сельдерей что-то импортирует из настроек, а обработчик журнала импортируется из настроек - циклический импорт? Что, если поместить LogHandler в settings.py, создать задачу в tasks.py и LogHandler вызовет эту задачу?   -  person demalexx    schedule 17.07.2012
comment
Да, я сделал это ... для того, чтобы LogHandler вызвал tasks.py, ему все равно нужно импортировать analytics / tasks.py, который, в свою очередь, импортирует celery.task. Выдает ту же ошибку.   -  person Taher Saeed    schedule 17.07.2012


Ответы (1)


Я нашел решение.

Проблема заключалась в том, что «если ваш settings.py указывает собственный класс обработчика и файл, определяющий этот класс, также импортирует settings.py, произойдет циклический импорт».

Чтобы решить эту проблему, нам нужно выполнить импорт в теле метода, а не в файле, определяющем класс.

Вот мой собственный LogHandler:

import logging
#Do not import settings here, as this would lead to circular import.


#This custom log handler parses the message and inserts the entry to the DynamoDB tables.
 class LogHandler(logging.Handler):
   def __init__(self):
    logging.Handler.__init__(self)
    self.report_logger = logging.getLogger('reporting')
    self.report_logger.setLevel(logging.INFO)

   def emit(self, record):
    #Submit the task to "reporting" queue to be picked up and processed by the worker lazily.
    #myApp.analytics.tasks imports celery.task
    from myApp.analytics import tasks
    tasks.push_row_to_dynamodb.apply_async(args=[record])
    return 

Надеюсь, это кому-то поможет.

person Taher Saeed    schedule 17.07.2012