[Fixed]-Log all errors to console or file on Django site

13đź‘Ť

âś…

It’s a bit extreme, but for debugging purposes, you can turn on the DEBUG_PROPAGATE_EXCEPTIONS setting. This will allow you to set up your own error handling. The easiest way to set up said error handling would be to override sys.excepthook. This will terminate your application, but it will work. There may be things you can do to make this not kill your app, but this will depend on what platform you’re deploying this for. At any rate, never use this in production!

For production, you’re pretty much going to have to have extensive error handling in place. One technique I’ve used is something like this:

>>> def log_error(func):
...     def _call_func(*args, **argd):
...         try:
...             func(*args, **argd)
...         except:
...             print "error" #substitute your own error handling
...     return _call_func
...
>>> @log_error
... def foo(a):
...     raise AttributeError
...
>>> foo(1)
error

If you use log_error as a decorator on your view, it will automatically handle whatever errors happened within it.

The process_exception function is called for some exceptions (eg: assert(False) in views.py) but process_exception is not getting called for other errors like ImportErrors (eg: import thisclassdoesnotexist in urs.py). I’m new to Django/Python. Is this because of some distinction between run-time and compile-time errors?

In Python, all errors are run-time errors. The reason why this is causing problems is because these errors occur immediately when the module is imported before your view is ever called. The first method I posted will catch errors like these for debugging. You might be able to figure something out for production, but I’d argue that you have worse problems if you’re getting ImportErrors in a production app (and you’re not doing any dynamic importing).

A tool like pylint can help you eliminate these kinds of problems though.

👤Jason Baker

6đź‘Ť

The process_exception function is
called for some exceptions (eg:
assert(False) in views.py) but
process_exception is not getting
called for other errors like
ImportErrors (eg: import
thisclassdoesnotexist in urs.py). I’m
new to Django/Python. Is this because
of some distinction between run-time
and compile-time errors?

No, it’s just because process_exception middleware is only called if an exception is raised in the view.

I think DEBUG_PROPAGATE_EXCEPTIONS (as mentioned first by Jason Baker) is what you need here, but I don’t think you don’t need to do anything additional (i.e. sys.excepthook, etc) if you just want the traceback dumped to console.

If you want to do anything more complex with the error (i.e. dump it to file or DB), the simplest approach would be the got_request_exception signal, which Django sends for any request-related exception, whether it was raised in the view or not.

The get_response and handle_uncaught_exception methods of django.core.handlers.BaseHandler are instructive (and brief) reading in this area.

without having to add any additional
exception handling to the code. I’ve
never seen exception handling around
import statements.

Look around a bit more, you’ll see it done (often in cases where you want to handle the absence of a dependency in some particular way). That said, it would of course be quite ugly if you had to go sprinkling additional try-except blocks all over your code to make a global change to how exceptions are handled!

👤Carl Meyer

2đź‘Ť

First, there are very few compile-time errors that you’ll see through an exception log. If your Python code doesn’t have valid syntax, it dies long before logs are opened for writing.

In Django runserver mode, a “print” statement writes to stdout, which you can see. This is not a good long-term solution, however, so don’t count on it.

When Django is running under Apache, however, it depends on which plug-in you’re using. mod_python isn’t easy to deal with. mod_wsgi can be coerced into sending stdout and stderr to a log file.

Your best bet, however, is the logging module. Put an initialization into your top-level urls.py to configure logging. (Or, perhaps, your settings.py)

Be sure that every module has a logger available for writing log messages.

Be sure that every web services call you make has a try/except block around it, and you write the exceptions to your log.

👤S.Lott

1đź‘Ť

👤jaimechen

-1đź‘Ť

If you are on a *nix system you could

write to a log (eg. mylog.txt) in python
then run “tail -f mylog.txt” in the console

this is a handy way to view any kind of log in near real time

👤

Leave a comment