kraiz / django-crontab

dead simple crontab powered job scheduling for django.
Other
842 stars 112 forks source link

How to setup logging in project? #83

Open carsonwah opened 6 years ago

carsonwah commented 6 years ago

Situation

I have read https://github.com/kraiz/django-crontab/issues/31 and https://github.com/kraiz/django-crontab/issues/67. I have tried the following setting:

LOGGERS = {
# ...
'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'formatter': 'normal',
        },
        'cron_log_file': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': '/var/log/uwsgi/scheduled_jobs.log',
            'formatter': 'normal'
        },
    },
    'loggers': {
        '': {
            'handlers': ['console'],
            'level': 'INFO',
        },
        'django_crontab': {  # To override the default logger from the library
            'handlers': ['console', 'cron_log_file'],  # Both doesn't work
            'level': 'DEBUG',
            'propagate': True,
        },
    },

CRONJOBS:

('*/1 * * * *', 'scheduled_jobs.cron.auto_func', '>> /var/log/uwsgi/scheduled_jobs.log')

Observation

This setup tests both StreamHandler, FileHandler. Both doesn't work. Only an empty log file is created. I also tested /tmp/xxxxx.log, still no luck.

It is logging correctly when I run manage.py crontab run xxxxx, even if I do not specify 'django_crontab' logger.

Question

Anyway, thanks for the great work on this package.

carsonwah commented 6 years ago

After messing around, I am able to make it work. There are actually 2 different issues on each handler itself.

Using FileHandler

# In the cron py file
import logging
logger = logging.getLogger(__name__)
# e.g. The namespace is something like "cron_app.cron"

# ==========

# setting.py
LOGGERS = {
    'formatters': {
        'normal': {
            'format': '[%(levelname)s] %(asctime)s | %(name)s:%(lineno)d | %(message)s'
        },
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'formatter': 'normal',
        },
        'cron_log_file': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': '/somewhere/scheduled_jobs.log',
            'formatter': 'normal'
        },
    },
    'loggers': {
        '': {
            'handlers': ['console'],
            'level': 'INFO',
        },
        'cron_app.cron': {  # The namespace of the logger above
            'handlers': ['cron_log_file'],
            'level': 'DEBUG',
            'propagate': True,
        },
    },

The log will be written to /somewhere/scheduled_jobs.log.

However in this case, whenever we run cron_app.cron module, (for example manage.py test), it will log into the file, which is not desirable. I just want those log coming from real cron job.

Using StreamHandler

This method solves the issue above. The original issue with StreamHandler is that python logging.StreamHandler by default redirects all output to stderr, so there is nothing when using >> to redirect them.

Just include stderr and things work like charm now.

('*/1 * * * *', 'cron_app.cron.some_func', '>> /somewhere/scheduled_jobs.log 2>&1')  # Redirect all stderr to stdout destination

I guess this issue is solved. Just write them down to help others and see if you have anything to add. Thanks so much.