102

The release notes say:

Django 1.3 adds framework-level support for Python’s logging module.

That's nice. I'd like to take advantage of that. Unfortunately the documentation doesn't hand it all to me on a silver platter in the form of complete working example code which demonstrates how simple and valuable this is.

How do I set up this funky new feature such that I can pepper my code with

logging.debug('really awesome stuff dude: %s' % somevar)

and see the file "/tmp/application.log" fill up with

18:31:59 Apr 21 2011 awesome stuff dude: foobar
18:32:00 Apr 21 2011 awesome stuff dude: foobar
18:32:01 Apr 21 2011 awesome stuff dude: foobar

What's the difference between the default Python logging and this 'framework-level support'?

Timo
  • 2,922
  • 3
  • 29
  • 28
John Mee
  • 50,179
  • 34
  • 152
  • 186

2 Answers2

190

I truly love this so much here is your working example! Seriously this is awesome!

Start by putting this in your settings.py

LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'formatters': {
        'standard': {
            'format' : "[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s",
            'datefmt' : "%d/%b/%Y %H:%M:%S"
        },
    },
    'handlers': {
        'null': {
            'level':'DEBUG',
            'class':'django.utils.log.NullHandler',
        },
        'logfile': {
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': SITE_ROOT + "/logfile",
            'maxBytes': 50000,
            'backupCount': 2,
            'formatter': 'standard',
        },
        'console':{
            'level':'INFO',
            'class':'logging.StreamHandler',
            'formatter': 'standard'
        },
    },
    'loggers': {
        'django': {
            'handlers':['console'],
            'propagate': True,
            'level':'WARN',
        },
        'django.db.backends': {
            'handlers': ['console'],
            'level': 'DEBUG',
            'propagate': False,
        },
        'MYAPP': {
            'handlers': ['console', 'logfile'],
            'level': 'DEBUG',
        },
    }
}

Now what does all of this mean?

  1. Formaters I like it to come out as the same style as ./manage.py runserver
  2. Handlers - I want two logs - a debug text file, and an info console. This allows me to really dig in (if needed) and look at a text file to see what happens under the hood.
  3. Loggers - Here is where we nail down what we want to log. In general django gets WARN and above - the exception (hence propagate) is the backends where I love to see the SQL calls since they can get crazy.. Last is my app were I have two handlers and push everything to it.

Now how do I enable MYAPP to use it...

Per the documentation put this at the top of your files (views.py)..

import logging
log = logging.getLogger(__name__)

Then to get something out do this.

log.debug("Hey there it works!!")
log.info("Hey there it works!!")
log.warn("Hey there it works!!")
log.error("Hey there it works!!")

Log levels are explained here and for pure python here.

rh0dium
  • 6,811
  • 4
  • 46
  • 79
  • 9
    i followed the above steps. file is created but nothing is written to it. pleas help – Vivek S Apr 10 '12 at 06:52
  • 13
    @InternalServerError you need to replace MYAPP with the name of your app in the loggers section. – Rog Jun 18 '12 at 14:24
  • Note: you don't need everything from the above snippet if all you want to do is add logging to files. Just add the "logfile" handler and the "MYAPP" logger. – Dan Benamy Nov 28 '12 at 01:37
  • 9
    You bet! Replace 'MYAPP' with '' – rh0dium Apr 10 '13 at 20:21
  • 1
    just in case 'MYAPP' is the name of the folder that contains settings.py – Bibek Shrestha Jun 30 '13 at 16:27
  • I did this it works fine in views.py but I have another folder within the same project it doesnt work. Can you help me please? – Sohaib Jul 05 '13 at 08:47
  • 11
    For clarification, whatever you call the logger in `settings.py`, i.e. `MYAPP` in this example, also has be the parameter in the call to `logging.getLogger`. Therefore, if your project contains many self-contained apps and you want them to use a common logger you need to use `logging.getLogger('MYAPP')` instead of `logging.getLogger(__name__)` – rhunwicks Aug 29 '13 at 13:42
  • Blank file is created. please suggest any solution. – Mohini Jan 30 '15 at 14:00
  • Blank files are created in debug=True mode, locally. – A.J. Oct 27 '15 at 19:15
  • 3
    This works great. Had to use 'class': 'logging.NullHandler' because 'django.utils.log.NullHandler' is no longer valid, but the rest worked for me in 1.11 – JacquelineIO Sep 06 '17 at 02:45
  • 1
    this solution must be DEPRECATED because it does not work at all – redress Jun 21 '18 at 21:30
5

Based partially on the logging config suggested by rh0dium and some more research I did myself, I started assembling an example Django project with nice logging defaults – fail-nicely-django.

Sample logfile output:

2016-04-05 22:12:32,984 [Thread-1    ] [INFO ] [djangoproject.logger]  This is a manually logged INFO string.
2016-04-05 22:12:32,984 [Thread-1    ] [DEBUG] [djangoproject.logger]  This is a manually logged DEBUG string.
2016-04-05 22:12:32,984 [Thread-1    ] [ERROR] [django.request      ]  Internal Server Error: /
Traceback (most recent call last):
  File "/Users/kermit/.virtualenvs/fail-nicely-django/lib/python3.5/site-packages/django/core/handlers/base.py", line 149, in get_response
    response = self.process_exception_by_middleware(e, request)
  File "/Users/kermit/.virtualenvs/fail-nicely-django/lib/python3.5/site-packages/django/core/handlers/base.py", line 147, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/kermit/projekti/git/fail-nicely-django/djangoproject/brokenapp/views.py", line 12, in brokenview
    raise Exception('This is an exception raised in a view.')
Exception: This is an exception raised in a view.

The detailed usage is explained in the README, but essentially, you copy the logger module to your Django project and add from .logger import LOGGING at the bottom of your settings.py.

metakermit
  • 21,267
  • 15
  • 86
  • 95