Django logging to console
Asked Answered
S

3

39

I'm trying to set up a logger that will log to the console (I want this because I'm using Heroku with Papertrails (Heroku's logging addon) and stuff written to the console will show up in Papertrails, making it filterable and all the nice Papertrail features.)

In settings I was first trying the following:

LOGGING = {
    'handlers' = {
        'file': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': 'mysite.log',
            'formatter': 'verbose'
        },
        'console':{
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
        },
    },
    (...)
    'loggers'={
        (...)
        'page_processors': {
            'handlers': ['console','file'],
            'level': 'DEBUG',
        }
    }
    (...)
}

as per the Django's logging page (for those who don't use Mezzanine, page_processors are what Mezzanine runs whenever you open a page; you can think of them as being like Django's views, but they only do the context, not the rendering).

On page_processors.py I have

import logging
logger = logging.getLogger(__name__)

@process_for(MyPage):
def myfunc(request, Page):
    logger.info('page_processor logging test')
    print 'my page_processor print'
    (...)

When I refresh the page I don't see the logger but I see the print AND the log to the file:

[02/Mar/2014 23:07:10] INFO [myApp.page_processors:13] page_progessor logging test

and so I know the logic is working. After googling a bit, I found this and this page that addresses precisely this issue. He says that by default logging.StreamHandler logs to STDERR. If we want to log to STDOUT you should add the keyword argument 'stream' to the logging.StreamHandler construct, and so configure the handler as such:

'handlers':{
    (...)
    'console':{
        'level': 'DEBUG',
        'class': 'logging.StreamHandler',
        'stream': sys.stdout
    },
}

Turns out this still doesn't work, and I don't get any error or anything, and I still see the print and the file log. Just not the console logger.

What's going on?

EDIT: I tried this, doesn't make a difference.

Sanctus answered 2/3, 2014 at 23:4 Comment(0)
S
46

I finally got it. Here's what was happening.

When you define a logger using getLogger, you give a logger a name, in this case

logger = logging.getLogger(__name__)

and you then have to define how a logger with that name behaves in the LOGGING configuration. In this case, since that file is inside a module, the logger's name becomes myApp.page_processors, not page_processors, so the logger named 'page_processors' in the LOGGING dict is never called. So why was the logging to the file working? Because in the (...) that I show in the code there is another logger named 'myApp' that apparently gets called instead, and that one writes to the file.

So the solution to this question is just to properly name the logger:

LOGGING = {
    # (...)
    'loggers': {
        # (...)
        'myApp.page_processors': {
            'handlers': ['console','file'],
            'level': 'DEBUG',
        }
    }
    # (...)
}
Sanctus answered 3/3, 2014 at 10:52 Comment(0)
S
33

The following script:

import logging, logging.config
import sys

LOGGING = {
    'version': 1,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'stream': sys.stdout,
        }
    },
    'root': {
        'handlers': ['console'],
        'level': 'INFO'
    }
}

logging.config.dictConfig(LOGGING)
logging.info('Hello')

writes Hello to sys.stdout, as can be verified by piping its output to a file. So your problem is likely to be somewhere else (or possibly that sys.stdout isn't what you expect). You could try with sys.__stdout__ to see if that makes a difference.

Sedimentary answered 3/3, 2014 at 8:30 Comment(2)
Thanks. __ stdout __ doesn't work though. Yeah, I can believe that there's nothing wrong with that code (after all, I took it from elsewhere), but it's strange that even logging to a file works. Any other suggestions?Sanctus
This does not seem to log anything on server 500 errors. Any ideas?Crowned
P
15

I am writing this for easy understanding dummies like me.

In settings.py

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'app_api': {
            'handlers': ['console'],
            'level': 'INFO',
        },
    },
    }

Somewhere in your application views

import logging
logger = logging.getLogger('app_api') #from LOGGING.loggers in settings.py

try:
    one = 1/0
except Exception as e:
    logger.error(e)
Prattle answered 18/8, 2019 at 7:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.