5

I have implemented custom commands in Django, and their exceptions aren't logged in my log file.

I created an application my_app_with_commands which contains a directory management/commands in which I implemented some commands.

A sample command, could be like this, which crashed due to an exception:

import logging
from django.core.management.base import BaseCommand


class Command(BaseCommand):
    help = 'Do something usful'
    log = logging.getLogger(__name__)

    def handle(self, *args, **options):
        self.log.info('Starting...')
        raise RuntimeError('Something bad happened')
        self.log.info('Done.')

And my logging configuration is like this:

LOGGING = { 
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'normal': {
            'format': '%(asctime)s %(module)s %(levelname)s %(message)s',
        }
    },  
    'handlers': {
        'file': {
            'level': 'INFO',
            'class': 'logging.FileHandler',
            'filename': os.path.join(BASE_DIR, '..', 'logs', 'my_log.log'),
            'formatter': 'normal',
        },
        'mail_admins': {
            'level': 'ERROR',
            'class': 'django.utils.log.AdminEmailHandler',
            'include_html': True,
        }
    },  
    'loggers': {
        'django': {
            'handlers': ['file'],
            'level': 'INFO',
            'propagate': True,
        },
        'my_app_with_commands': {
            'handlers': ['file', 'mail_admins'],
            'level': 'INFO',
            'propagate': True,
        },
    },  
}

When I run the command, the calls to the logger are successfully saved to my_log.log file:

2016-09-22 11:37:01,514 test INFO Starting...

But the exception with each traceback, is displayed in stderr where the command had been called:

[mgarcia@localhost src]$ ./manage.py test
Traceback (most recent call last):
  File "./manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/home/mgarcia/anaconda3/envs/my_env/lib/python3.5/site-packages/django/core/management/__init__.py", line 353, in execute_from_command_line
    utility.execute()
  File "/home/mgarcia/anaconda3/envs/my_env/lib/python3.5/site-packages/django/core/management/__init__.py", line 345, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/mgarcia/anaconda3/envs/my_env/lib/python3.5/site-packages/django/core/management/base.py", line 348, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/mgarcia/anaconda3/envs/my_env/lib/python3.5/site-packages/django/core/management/base.py", line 399, in execute
    output = self.handle(*args, **options)
  File "/home/mgarcia/my_project/src/my_app_with_commands/management/commands/test_command.py", line 11, in handle
    raise RuntimeError('Something bad happened')
RuntimeError: Something bad happened

I can implement in each of my commands a try/except block, and manually log the exception. But can I just capture the exception and save it to my log file instead of stderr using Django settings?

1
  • Instead of modifying each command you can just write a decorator and use that: @catch_and_log_exceptions;def handle(self, ...) where the decorator contains the try: return method(self, *args, **kwargs); except Exception as e: self.log(...). Commented Sep 22, 2016 at 12:53

1 Answer 1

1

One of the ways - you can edit manage.py file to add a try/except block in it:

log = logging.getLogger('my_app_with_commands')
# ...
try:
    execute_from_command_line(sys.argv)
except Exception as e:
    log.error('your exception log')
    raise e
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.