Celery worker does not write logs when detached

Viewed 1294

I have a Django application and I use celery & rabbitmq to execute async tasks. I have configured celery to write logs to file, and when I execute

celery -A project_name -b <broker_url> worker -l INFO

everything works fine and the logs are printed both in console and into the file.

However, when I execute the aforementioned command with -D option, i.e. detach the worker, the file is no longer appended with logs.

My logging configuration:

LOGGING = {
'version': 1,
'disable_existing_loggers': True,
'formatters': {
    'standard': {
        'format': "[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s",
        'datefmt': "%d/%b/%Y %H:%M:%S"
    },
},
'handlers': {
    'null': {
        'level': LOGGING_LEVEL,
        'class': 'logging.NullHandler',
    },
    'logfile': {
        'level': LOGGING_LEVEL,
        'class': 'logging.handlers.RotatingFileHandler',
        'filename': log_file_path,
        'maxBytes': 5000000,
        'backupCount': 2,
        'formatter': 'standard',
    },
    'console': {
        'level': LOGGING_LEVEL,
        'class': 'logging.StreamHandler',
        'formatter': 'standard'
    },
},
'loggers': {
    'django': {
        'handlers': ['console'],
        'propagate': True,
        'level': "WARNING",
    },
    'django.db.backends': {
        'handlers': ['console'],
        'level': "INFO",
        'propagate': False,
    },
    'celery': {
        'handlers': ['console', 'logfile'],
        'level': LOGGING_LEVEL,
    },
}}

The celery.py:


from __future__ import absolute_import, unicode_literals

import os

from celery import Celery
from celery.signals import setup_logging

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'my_service.settings')

app = Celery('my_service')

app.config_from_object('django.conf:settings', namespace='CELERY')


@setup_logging.connect
def config_loggers(*args, **kwags):
    from logging.config import dictConfig
    from board_ownership_service import settings
    dictConfig(settings.LOGGING)


# Load task modules from all registered Django app configs.
app.autodiscover_tasks()

Am I missing some configuration for the logging?

===========================================

UPDATE

I have changed the logfile handler with TimedRotatingFileHandler as follows:

'logfile': {
            'level': LOGGING_LEVEL,
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'filename': log_file_path,
            'when': 'D',  # this specifies the interval
            'interval': 1,  # defaults to 1, only necessary for other values
            'backupCount': 30,  # how many backup file to keep, 10 days
            'formatter': 'standard',
        }

Now, I end up with a file named logs_yyyyMMdd.logs and when I execute:

   celery -A project_name -b <broker_url> worker -l INFO --logfile logs20210526.logs -D

I can see the logs in the file. My question is what happens when the day changes? Why celery, when executed with -D, does not use the logging configuration?

1 Answers

I made it work as follows.

I created a function in settings.py

def config_logging():
    timestamp = datetime.now().strftime('%Y%m%d')
    filename = f"logs_{timestamp}.log"
    log_file_path = join(LOGS_PATH, filename)
    logging_level = "DEBUG" if env("DEBUG") else "INFO"
    logging_config = {
        'version': 1,
        'disable_existing_loggers': True,
        'formatters': {
            'standard': {
                'format': "[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s",
                'datefmt': "%d/%b/%Y %H:%M:%S"
            },
        },
        'handlers': {
            'null': {
                'level': logging_level,
                'class': 'logging.NullHandler',
            },
            'logfile': {
                'level': logging_level,
                'class': 'logging.handlers.TimedRotatingFileHandler',
                'filename': log_file_path,
                'when': 'D',  # this specifies the interval
                'interval': 1,  # defaults to 1, only necessary for other values
                'backupCount': 30,  # how many backup file to keep, 10 days
                'formatter': 'standard',
            },
            'console': {
                'level': logging_level,
                'class': 'logging.StreamHandler',
                'formatter': 'standard'
            },
        },
        'loggers': {
            'django': {
                'handlers': ['console'],
                'propagate': True,
                'level': "WARNING",
            },
            'django.db.backends': {
                'handlers': ['console'],
                'level': "INFO",
                'propagate': False,
            },
            'celery': {
                'handlers': ['console', 'logfile'],
                'level': logging_level,
            },
        }
    }
    dictConfig(logging_config)
    return filename, logging_config


log_filename, LOGGING = config_logging()
logger = logging.getLogger("celery")

with the logging configuration, and then in celery.py I modified the code:

@setup_logging.connect
def config_loggers(*args, **kwags):
    config_logging()


logger = logging.getLogger("celery")

Now I can see the logs in the file even when the worker is detached.

Related