2

I was expecting that the following code would output both log lines

import logging

log = logging.getLogger('hello')
log.setLevel(logging.DEBUG)
print(log.getEffectiveLevel())
log.debug('debug log')
log.critical('critical log')

The output is

10
critical log

The level is correctly set to 10 (which corresponds to DEBUG) and despite this log.debug('debug log') does not output anything - why?

3
  • you mean print the log to stdout or stderr? Commented Sep 19, 2020 at 21:03
  • @MiguelTrejo: why would there be a difference? debug messages would be printed elsewhere than critical ones? And this elsewhere would not be impacted by .setLevel()? Commented Sep 19, 2020 at 21:37
  • 1
    You only set the level on the logger itself, not the initial handler that will be used to print the log message to standard error. Handlers and loggers have separate levels, so that (for instance) a single logger can write debugging messages to the console, but only serious errors to an SMTP handler to notify someone of a problem that needs to be addressed. Commented Sep 19, 2020 at 22:05

3 Answers 3

3

You haven't configured the logging system, so it's still using the defaults (level WARN for the root logger).

https://docs.python.org/3/library/logging.html#logging.basicConfig says basicConfig

Does basic configuration for the logging system by creating a StreamHandler with a default Formatter and adding it to the root logger.

Configuring the logging system with basicConfig first will create a handler and formatter that your logger will use:

logging.basicConfig()
log = logging.getLogger('hello')
log.setLevel(logging.DEBUG)
print(log.getEffectiveLevel())
log.debug('debug log')
log.critical('critical log')

Outputs:

10
DEBUG:hello:debug log
CRITICAL:hello:critical log

In Logger.callHandlers, each handler compares the log record's level with its level. If there aren't any handlers, it will use the default of WARNING.

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

6 Comments

Thanks - so in my case my log output is still driven by the default WARNING level despite being effectively set to DEBUG?
Yes, you set your logger to DEBUG, but it's not connected to a handler (there aren't any yet). Try print('handlers=', logging.getLogger().handlers) with and without basicConfig. The docs on Handler (docs.python.org/3/library/logging.html#logging.Handler) show that the __init__(level=NOTSET) method takes a level parameter.
But if there are no handlers, how could the critical level message be displayed? Because it was handled by the root level logger? (and despite having its own logger somehow bubbled up to the root logger?)
If there aren't any, it uses the default level of WARNING: github.com/python/cpython/blob/master/Lib/logging/…
@WoJ the reason why something is displayed is that when no handlers are configured, there is an internal "handler of last resort" which is used, and which has a level of WARNING. Documented here: docs.python.org/3/library/…
|
1

With a StreamHandler it will

sends logging output to streams such as sys.stdout, sys.stderr or any file-like object"

according to the documentation

import logging 
import sys

# Initialize Logger and set Level to DEBUG
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)

# Initialize a Handler to print to stdout
handler = logging.StreamHandler(sys.stdout)

# Format Handler output
logFormatter = logging.Formatter(
    "%(asctime)s %(message)s", datefmt="%m/%d/%Y %I:%M:%S %p"
)
handler.setFormatter(logFormatter)

# Set Handler Level to DEBUG
handler.setLevel(logging.DEBUG)
logger.addHandler(handler)

logger.debug('Debug Info')
>>> 09/19/2020 09:01:00 PM Debug Info

Comments

0

You need to add stream handler

import logging

log = logging.getLogger('hello')
log.setLevel(logging.DEBUG)

# # Create a file handler to store the logs
file_handler = logging.FileHandler('test.log')
log.addHandler(file_handler)

# # Send output to terminal
stream_handler = logging.StreamHandler()
log.addHandler(stream_handler)

log.debug('debug log')

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.