Thursday, March 8, 2012

Using JSON logging in Django (and Python in general)

For a while now, I've wanted to output JSON in my Django log files instead of plain text. However, Google searches and the Python and Django documentations fail to provide a single example that contains all of the required bits of information required to make it work.

Specifically, you need to know how to define a custom formatter in a dictionary config for a logger. All the examples are in UML or use the old-style method of instantiating a formatter and assigning it to a handler.

This makes use of the python-json-logger, available here:

https://github.com/madzak/python-json-logger

So, here is a working example. Simply do this in your own code and you'll be all set. Note that in Django you don't have to deal with the dictConfig at all -- just put the right things in your dictionary and Django will do the rest.

#!/usr/bin/env python


import logging
from logging.config import dictConfig
import jsonlogger


log_config = {
    'version': 1,


    'formatters': {
        'json': {
            '()': 'jsonlogger.JsonFormatter',
            'fmt': '%(levelname)s %(asctime)s %(message)s',
        },
    },


    'handlers': {
        'stream': {
            'level': 'DEBUG',
            'formatter': 'json',
            'class': 'logging.StreamHandler',
        },
    },


    'loggers':  {
        'my_logger': {
        'handlers': ['stream'],
        'level': 'DEBUG',
        'propagate': True,
        },
    }


}


dictConfig(log_config)
logger = logging.getLogger('my_logger')


logger.debug('foo')





6 comments:

  1. Hello,

    I am not advanced in django so appologize me for the question, where exactly should I put that code? views.py, settings.py...or?

    thanks

    ReplyDelete
    Replies
    1. If you're using Django 1.3 or greater, the LOGGING dictionary will already exist in settings.py. Just update it with the info in the example.

      If you're using an older version of Django, you're on your own with the logging.

      Delete
  2. Ok thanks, yes I am using 1.3.1 -

    Should I replace this entire part with that part beggining with

    #!/usr/bin/env python - isnt this a comment?

    LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
    'mail_admins': {
    'level': 'ERROR',
    'class': 'django.utils.log.AdminEmailHandler'
    }
    },
    'loggers': {
    'django.request': {
    'handlers': ['mail_admins'],
    'level': 'ERROR',
    'propagate': True,
    },
    }
    }

    ReplyDelete
    Replies
    1. No, only add/edit the contents of the existing LOGGING dictionary.

      And, of course, makes sure python-json-logger is installed and imported.

      Delete