1

I have log a file:

[loggers]
keys=root

[handlers]
keys=consoleHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=INFO
handlers=consoleHandler

[handler_consoleHandler]
class=StreamHandler
level=INFO
formatter=simpleFormatter
args=(sys.stdout,)

[formatter_simpleFormatter]
format=%(asctime)s %(levelname)s %(message)s
datefmt=%Y-%m-%d %H:%M:%S

Then, when I run the following code, it does not print the dubug message. why is that?

from logging import getLogger
from logging.config import fileConfig
fileConfig('/Users/zech/Dropbox/git/micronota/micronota/log.cfg')
l = getLogger()
l.setLevel('DEBUG')
l.debug('adfa')
l.info('info')  # this works and outputs 'info'
2
  • 1
    I believe (though not 100% certain) it's because setLevel expects a numeric level (docs.python.org/2/library/logging.html#logging-levels) Does it work if you do: l.setLevel(logging.DEBUG)? (you'll need to import logging at the top of the file) Commented Nov 2, 2016 at 19:01
  • in python 3.5, you can set with either numeric or string as well. Commented Nov 2, 2016 at 19:17

2 Answers 2

4

Ah, I got it!

You also need to set the level in your handlers.

In your config file, your StreamHandler has level INFO. That means that even though your root logger l is going to emit the l.debug('adfa') message, the handler itself is not going to register it. This is intended so you can have a finer control on what messages to log. For instance, let's say you want to have two handlers: one that writes to the terminal and another that writes to a file. In the terminal, it might be OK to output everything, but you might get concerned the files get too big, right? So you create a FileHandler with its level set to WARN level, so you could place l.debug(...) statements in your code which would get printed to the console, but not to the file.

If you don't wanna change your configuration file, you can do this:

l = getLogger()
l.setLevel('DEBUG')
for handler in l.handlers:
    handler.setLevel('DEBUG')
l.debug('adfa')

From the docs for Python 3.1 (bit older, but it looks like the sentence I'm gonna paste below was removed in the Python 3.5 docs)

Why are there two setLevel() methods? The level set in the logger determines which severity of messages it will pass to its handlers. The level set in each handler determines which messages that handler will send on.

Sign up to request clarification or add additional context in comments.

2 Comments

Seriously, I told myself to try the "good practice" of using the logging module, but I lost so much time with weird implementation things like that. No doubt it made some sense to do that, but logging is definitely not as simple as it should be in order to be more widely used...
This answer provides another solution to your problem (calling basicConfig): stackoverflow.com/a/46700675
0

You've set your log level as INFO. You can replace:

[logger_root]
level=INFO
handlers=consoleHandler

[handler_consoleHandler]
class=StreamHandler
level=INFO
formatter=simpleFormatter
args=(sys.stdout,)

With

[logger_root]
level=DEBUG
handlers=consoleHandler

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)

2 Comments

Thanks. note I set the level after the fileConfig call. Can't you change the level after reading the config file?
I see. Would you be able to print l.getEffectiveLevel() to tell us what level is set before and after you do l.setLevel('DEBUG') ?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.