Confused about logger config from within Python (3)

A

andrew cooke

When I use a config file things seem to work (in other projects), but for my current code I hoped to configure logging from Python.

I distilled my problem down to the following test, which does not print anything. Please can someone explain why? I was expecting the module's logger to delegate to root, which has the DEBUG level set.

from logging import DEBUG, root, getLogger
from unittest import TestCase

class LoggingTest(TestCase):

def test_direct(self):
root.setLevel(DEBUG)
getLogger(__name__).debug("hello world")

Thanks,
Andrew
 
A

andrew cooke

similarly, if i run the following, i see only "done":

from logging import DEBUG, root, getLogger

if __name__ == '__main__':
root.setLevel(DEBUG)
getLogger(__name__).debug("hello world")
print('done')
 
D

Dave Angel

On Friday, 28 December 2012 21:56:46 UTC-3, Peter Otten wrote:
reading the damn docs you condescending *****?

You've made four posts this year to this forum, in two threads, to ask
for help. In that same year, Peter Otten has voluntarily helped others
with 325 messages. As far as I can see, he hasn't started any threads,
just helped where he could. So your way of giving thanks to him, and to
the hundreds of others who give so generously of their time, is to call
him a potty-name?

People like you make me rethink my own commitment to helping.
Fortunately, there aren't too many of you.
 
S

Steven D'Aprano

When I use a config file things seem to work (in other projects), but
for my current code I hoped to configure logging from Python.

I distilled my problem down to the following test, which does not print
anything. Please can someone explain why? I was expecting the module's
logger to delegate to root, which has the DEBUG level set.

from logging import DEBUG, root, getLogger
from unittest import TestCase

class LoggingTest(TestCase):
def test_direct(self):
root.setLevel(DEBUG)
getLogger(__name__).debug("hello world")


Nothing gets printed because you don't do anything except define a class.
Try instantiating the class, then calling the test_direct method. The
most convenient way to do so is with the unittest module:

# after defining the class above
import unittest
unittest.main()


which then prints:

py> unittest.main()
No handlers could be found for logger "__main__"
..
----------------------------------------------------------------------
Ran 1 test in 0.045s

OK


So you need a handler.
 
S

Steven D'Aprano

similarly, if i run the following, i see only "done":

from logging import DEBUG, root, getLogger

if __name__ == '__main__':
root.setLevel(DEBUG)
getLogger(__name__).debug("hello world")
print('done')


In Python 2.7, the above prints:

py> from logging import DEBUG, root, getLogger
py> root.setLevel(DEBUG)
py> getLogger(__name__).debug("hello world"); print("done")
No handlers could be found for logger "__main__"
done


In Python 3.2 and 3.3, the message about no handlers is not printed,
which is an interesting difference. (Somebody who knows more about the
logging package than I do might be able to state why that difference.) So
it would help if you told us what version of Python you're running.

This works as expected:


py> lg = getLogger(__name__)
py> lg.level = logging.DEBUG
py> lg.debug("hello world"); print("done")
DEBUG:__main__:hello world
done

since the default logging level is WARNING, as the tutorial explains:

The default level is WARNING, which means that only events of this level
and above will be tracked, unless the logging package is configured to do
otherwise.
[end quote]

http://docs.python.org/dev/howto/logging.html
 
T

Terry Reedy

I hope that means that http://bugs.python.org/issue994421 has finally
been fixed :)

I added an update ;-).

If Vijay wanted the message to be a warning rather than an exception,
the warnings module and mechanism could have been used (once it was
available -- I am not sure when that was). But I think a default handler
is even better.

Given that you disagreed with his disposition of the issue, you might
have posted to this list for other opinions.

I also hope you appreciate that Vijay has stuck with maintenance and
upgrade of the module for nearly a decade now.
 
R

Roy Smith

Terry Reedy said:
I added an update ;-).

If Vijay wanted the message to be a warning rather than an exception,
the warnings module and mechanism could have been used (once it was
available -- I am not sure when that was). But I think a default handler
is even better.

Having a default handler is clearly a good fix.
I also hope you appreciate that Vijay has stuck with maintenance and
upgrade of the module for nearly a decade now.

Absolutely.

BTW, I recently discovered a truly awesome thing about logging and
nosetests. Apparently, nose attaches a hander to the root logger at
debug level and buffers anything that gets sent there. If a test fails,
it prints anything that logger captured. So, for example (intentionally
breaking one of my tests):

-------------------- >> begin captured logging << --------------------
requests.packages.urllib3.connectionpool: INFO: Starting new HTTP
connection (1): localhost.lic.songza.com
requests.packages.urllib3.connectionpool: DEBUG: "GET
/foo:80/api/v2/?format=json ('HTTP/1.1',)" 404 None
--------------------- >> end captured logging << ---------------------

This rocks!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top