Как регистрироваться в журнале celery вне задач celery (внутри представления django)?
Представьте конечную точку в проекте django
def my_view(request, my_id):
if is_request_valid(request):
logger = logging.getLogger('celery.task')
logger.info('Starting a task for a thing with ID %i', my_id)
my_cool_task.apply_async()
Теперь, согласно документам celery, это может войти в журнал, поскольку
Доступен специальный логгер под названием "celery.task", вы можете наследоваться от этого логгера, чтобы автоматически получать имя задачи и уникальный идентификатор как часть логов.
Но логгер "celery.task" работает только внутри задачи. Поэтому в представлении этот лог уйдет в никуда.
Кроме того, я играл с установкой некоторой переменной логирования внутри settings.py, а затем переназначил логирование сельдерея. Я играл с CELERY_WORKER_HIJACK_ROOT_LOGGER, но даже когда я использую корневой логгер, журналы не появляются в консоли. Не помогает и использование getLogger("celery").
Это кажется простым делом, но я целый день пытаюсь это сделать, пожалуйста, помогите.
UPD: Я видел пост на reddit с той же проблемой, но там нет ответов
Итак, как следует из вопроса, взломать логгер сельдерея невозможно.
Однако есть несколько обходных путей:
- Создайте задачу для ведения журнала, например
from celery.utils.log import get_task_logger
@shared_task
def log_stuff(level, message, *args, **kwargs):
get_task_logger().log(level, message, *args, **kwargs)
Однако это грязно по многим причинам: в основном потому, что ваш журнал будет выполнен, когда рабочий доберется до него, и это просто превратится в беспорядок.
- Зайдите в тот же файл. Зайдите в файл your_projects_name/settings.py, определите переменную
LOGGING
, например:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'simple': {
'format': '[%(levelname)s] %(message)s',
},
},
'handlers': {
'console': {
'level': 'INFO',
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'file': {
'level': 'INFO',
# with rotating handlers you can configure max size and other stuff
'class': 'logging.FileHandler',
'formatter': 'simple',
'filename': 'my_log.log',
},
# that's the most interesting part
'loggers':
'django': {
'handlers': ['file', 'console'],
'level': 'INFO',
},
'celery': {
'handlers': ['file', 'console'],
'level': 'INFO',
},
}
Примечание: ваша конфигурация протоколирования должна быть более сложной.
Теперь никаких дополнительных действий не требуется, учитывая настройку django celery по умолчанию из документации, и что ваша версия django - 4.2.11, а celery - 5.3.6 - на более старых версиях вы можете захотеть поиграть с celery.signals.setup_logging.
2-ое замечание: потоки настроены для отдельных процессов django и celery: вы не увидите их все в одном месте
- Рассмотрите возможность использования таких инструментов, как logstash, sentry, graypy, new relic - они соберут все журналы в одном месте. Я не пробовал ни один из них, но это то, что также используется.
Наконец, конечно, это может работать с чем угодно, не обязательно только с django.