Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Logging INFO to Django Server's STDOUT

Tags:

python

django

I'm setting up logging on a Django server. I want to be able to log arbitrary INFO-level strings to the server's standard out, so it appears alongside the standard Django messages that look like this:

[24/Feb/2014 20:37:03] "POST /v1/events/ HTTP/1.1" 201 0

Here is my current logging configuration:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse'
        }
    },
    'handlers': {
        'mail_admins': {
            'level': 'ERROR',
            'filters': ['require_debug_false'],
            'class': 'django.utils.log.AdminEmailHandler'
        },
        #'file': {
            #'level': 'DEBUG',
            #'class': 'logging.FileHandler',
            #'filename': '/tmp/djdebug.log',
        #},
        'console': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'stream': sys.stdout
        }
    },
    'loggers': {
        'django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
        },
        'django': {
            'handlers': ['console'],
            'propogate': True,
            'level': 'INFO'
        }
        #'django': {
            #'handlers': ['file'],
            #'propagate': True,
            #'level': 'DEBUG',
        #},
    }
}

In a models.py file in an app for my django project, I do the following at the top:

import logging
logger = logging.getLogger(__name__)

Then, within some code, I write run the following:

logger.info('triggering notifications')

The code hits the point where this is called, but nothing is written to the server's stdout. Am I missing something? I'm running this locally, and DEBUG = True, but I'd like the INFO messages to be displayed even in production with DEBUG = False.

like image 836
user1427661 Avatar asked Feb 24 '14 20:02

user1427661


1 Answers

__name__ is the name of the python module that contains the logger. So, to make your logger work, you should rename your logger in settings.py from django to name of the module from where you calling getLogger. Second option - just change __name__ to django:

logger = logging.getLogger('django')

late update to your comment:

Yeah, but I still want all of my loggers namespaced. I'm just wondering if there's a way to set a "base line" configuration for all modules and have everything automatically inherit from that. Using 'django' for everything is out of the question, totally unmodular.

You just need to add 'your_project_name' logger to loggers list. The dotted paths of logger names define a hierarchy. For example, if you need, let's say, file log for 'some_application' in your project and all other applications log messages (INFO level) should going to console only, then your loggers list can look like this:

'loggers': {
    'django.request': {
        'handlers': ['mail_admins'],
        'level': 'ERROR',
        'propagate': True,
    },
    'django': {
        'handlers': ['console'],
        'propagate': True,
        'level': 'INFO'
    },

    #...

    'your_project_name': {
        'handlers': ['console'],
        'propagate': False,
        'level': 'INFO',
    },
    'your_project_name.some_application': {
        'handlers': ['file'],
        'propagate': True, # propagate here to root project level
                           # logger to also print this message to console
        'level': 'DEBUG',
    },

    #...

    'your_project_name.some_application.models': {
        'handlers': ['mail_admins'], #, 'console']
        'propagate': True, # if file and console needed,
                           # but 'console' can be added to handlers
                           # and propagate set to False
                           # to avoid this log messages in file...
        'level': 'ERROR',
    },

}

Calling logger = logging.getLogger(__name__) in some_application will get you logger, that should log all messages to file and also propagate to root project logger to display them on console. All other applications modules __name__ will match only your root project logger: your_project_name that will print messages on console only. If needed you can, add one more level to tree, for example your_project_name.some_application.models that can use mail_admins handler to report some db problems to admins. You can change logger levels on different loggers in hierarchy of course!

like image 117
ndpu Avatar answered Oct 26 '22 18:10

ndpu