Ryan Detzel
Ryan Detzel

Reputation: 5599

How can I get Django to print the debug information to the console?

I'm using urlib to hit my app not a browser so I can't see the debug screen when an error occurs. What's the best way to send the normal debug info to the console or a file?

Edit: I'm already catching the output of the page but when I print that to the screen it's filled with tons of useless html. can I get just the error?

Upvotes: 46

Views: 106905

Answers (6)

Adam Easterling
Adam Easterling

Reputation: 2415

The best way to do this is to set up a logging handler for django.requests. You do this by adding the LOGGING setting to your settings.py file. An example is included below:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'formatters': {
        'verbose': {
            'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
        },
    },
    'handlers': {
        'console': {
            'level': 'NOTSET',
            'class': 'logging.StreamHandler',
            'formatter': 'verbose'
        }
    },
    'loggers': {
        '': {
            'handlers': ['console'],
            'level': 'NOTSET',
        },
        'django.request': {
            'handlers': ['console'],
            'propagate': False,
            'level': 'ERROR'
        }
    }
}

With this in place, you'll see a nice stack trace in your terminal every time a 500 response is returned.

For more information on Django's implementation of the Python logger, see the documentation about logging.

Upvotes: 19

Bojan Jovanovic
Bojan Jovanovic

Reputation: 1499

Ok guys, I think this an important thing to note, as it's year 2016 and many people are using Django Rest Framework instead of standard django forms, I've wasted 2 hours on figuring out why my exceptions are being handled by a renderer and it never gets to the middleware, the solution to the problem is simple.

http://www.django-rest-framework.org/api-guide/exceptions/#custom-exception-handling

So like this:

import traceback

from rest_framework.views import exception_handler

def custom_exception_handler(exc, context):
    # Call REST framework's default exception handler first,
    # to get the standard error response.
    response = exception_handler(exc, context)
    traceback.print_exc()
    return response

And then in settings define the exception handler as such:

REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'utils.custom_exception_handler.custom_exception_handler'
}

Upvotes: 4

Update - 2016

This post is still getting hits.

I recommend using one of the approaches below that use the built in logging system.

In the same way exceptions are piped to the admin email handler, you can send the data to a console logger, file logger, or anywhere else (solely, or in addition to the email handler.)

Original answer

Well, the easiest way is to set debug mode OFF and let django email you the error, since that literally takes 5 seconds: http://docs.djangoproject.com/en/dev/howto/error-reporting/

Otherwise, I'd write a middleware that logs the exception, but it's a little more of a pain if you want the stack trace. Here's the documentation.

import traceback
import sys
from __future__ import print_function

class ProcessExceptionMiddleware(object):
    def process_exception(self, request, exception):
        # Just print the exception object to stdout
        print(exception)

        # Print the familiar Python-style traceback to stderr
        traceback.print_exc()

        # Write the traceback to a file or similar
        myfile.write(''.join(traceback.format_exception(*sys.exc_info())))

Upvotes: 32

Anuvrat Parashar
Anuvrat Parashar

Reputation: 3110

I was getting 500 Internal Server Error and was not able to debug it as the code was not accessed through a browser and terminal didn't show the traceback. This bit of code in a middleware made all the difference:

import traceback
import sys

class ProcessExceptionMiddleware(object):
    def process_response(self, request, response):
        if response.status_code != 200:                
            print '\n'.join(traceback.format_exception(*sys.exc_info()))
        return response

Instead of processing the exception I, am processing the response object and printing the traceback when the status code not 200 and voila I can now see what is causing the error. Which in this particular case was an improperly indented block.

Yuji's answer above and the middleware documentation helped me reach this solution.

Upvotes: 5

Revil
Revil

Reputation: 145

The answer for this is to create a django middleware to catch all exeptions.

When you catch them, you can redirect them to whatever you want.

Documentation is here:

http://docs.djangoproject.com/en/dev/topics/http/middleware/#process-exception

Upvotes: 1

Seth
Seth

Reputation: 46443

If you're running the development server locally, you can just use print.

Also, you can use the logging module and redirect output to stdout. In settings.py put something like:

import logging.config

logging.config.fileConfig('/path/to/logging.conf')

Then make a logging.conf file:

[loggers]
keys=root

[handlers]
keys=consoleHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)

[formatter_simpleFormatter]
format=format=%(asctime)s - %(name)s - %(levelname)s - %(message)s

Check out the python documentation for more details and more examples.

Upvotes: 16

Related Questions