Logging exceptions in Django commands
<p>I have implemented custom commands in Django, and their exceptions aren't logged in my log file.</p>

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

<p>A sample command, could be like this, which crashed due to an exception:</p>

<pre><code>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.')
</code></pre>

<p>And my logging configuration is like this:</p>

<pre><code>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,
        },
    },  
}
</code></pre>

<p>When I run the command, the calls to the logger are successfully saved to <code>my_log.log</code> file:</p>

<pre><code>2016-09-22 11:37:01,514 test INFO Starting...
</code></pre>

<p>But the exception with each traceback, is displayed in <code>stderr</code> where the command had been called:</p>

<pre><code>[mgarcia@localhost src]$ ./manage.py test
Traceback (most recent call last):
  File "./manage.py", line 10, in &lt;module&gt;
    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
</code></pre>

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

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

<pre><code>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
</code></pre>

python django logging