A sane Django logging setup

2016-01-07 | #django, #solution, #webdev

Logging is important. VERY. Important, but it's also a nuisance to setup.

Django has some of the best default logging there is, but you can still easily super power it, with different info depth according to debugging settings, mailing, rotating filesystem logs and detailed request info.

Here's a setup I regularly use:

###[ LOGGING ]################################################################################################

LOGS_ROOT = os.path.join(BASE_DIR, 'logs')

LOGGING = {

'version': 1,

'disable_existing_loggers': True,

'formatters': {

'main': {

'format': '[%(asctime)s] by %(username)s |%(levelname)s:%(name)s: %(message)s (%(filename)s:%(lineno)d)',

'datefmt': "%Y-%m-%d %H:%M:%S"

}

},

'filters': {

'require_debug_true': {

'()': 'django.utils.log.RequireDebugTrue'

},

'require_debug_false': {

'()': 'django.utils.log.RequireDebugFalse'

},

'request': {

'()': 'django_requestlogging.logging_filters.RequestFilter'

}

},

'handlers': {

'null': {

'level': 'DEBUG',

'class': 'django.utils.log.NullHandler',

},

'console':{

'level': 'DEBUG',

'class': 'logging.StreamHandler',

'formatter': 'main'

},

'debug_file':{

'level' : 'DEBUG',

'class' : 'logging.handlers.RotatingFileHandler',

'filename' : LOGS_ROOT+'/debug.log',

'encoding': 'utf-8',

'maxBytes': 1024*1024*5, # 5MB

'backupCount' : 7,

'formatter': 'main',

'filters': ['require_debug_true']

},

'info_file':{

'level' : 'INFO',

'class' : 'logging.handlers.RotatingFileHandler',

'filename' : LOGS_ROOT+'/info.log',

'encoding': 'utf-8',

'maxBytes': 1024*1024*5, # 5MB

'backupCount' : 7,

'formatter': 'main',

'filters': ['require_debug_false']

},

'mail_admins': {

'level': 'ERROR',

'class': 'django.utils.log.AdminEmailHandler',

'formatter': 'main',

'filters': ['require_debug_false']

}

},

'loggers': {

'django': {

'handlers': ['null'],

'level': 'INFO',

'propagate': True,

},

'django.request': {

'handlers': ['mail_admins'],

'filters': ['request'],

'level': 'ERROR',

'propagate': False,

},

'default': {

'handlers': ['debug_file', 'info_file', 'mail_admins'],

'filters': ['request'],

'level': 'DEBUG',

'propagate' : False

}

}

}

Don't forget to install "django-requestlogging" for this and add it to your apps.

After that add "django_requestlogging.middleware.LogSetupMiddleware" to your MIDDLEWARE_CLASSES and you should be done.

Now you can use the default logger in every module by doing somthing like this:

import logging

_LOGGER = logging.getLogger('default')

...

_LOGGER.info('author ({author}) has been connected to article ({article})'.format(author=author, article=article))

...

_LOGGER.debug('I'll only be written if settings.debug == True')

...

_LOGGER.error('this did not work!')