Reputation: 24758
import logging
import sys
FORMAT3 = '%(asctime)s %(name)s %(levelname)s - %(message)s' # for root logger
logger = logging.getLogger("mylogger")
logger.setLevel(logging.DEBUG) # allow >= DEBUG
logging.basicConfig(format=FORMAT3) # creates a StreamHandler with a given Format and adding it to the root logger. The default stream is sys.stderr
# When a handler is created, the level is set to NOTSET (which causes all messages to be processed).
# root logger is created at WARNING level.
logger.debug("This is a debug message with propagate True") # why does this log, if root is at WARNING - (A)
logger.info("This is a info message with propagate True") # why does this log, if root is at WARNING - (B)
logger.warning("This is a warning message with propagate True")
logger.propagate = False # now logger has no handlers, logging.lastResort handler that permits >=WARNING will be used
logger.debug("This is a debug message after propagate is False") # does not log
logger.info("This is a info message after propagate is False") # does not log
# logging.lastResort = None
logger.warning("This is a warning message after propagate is False") # uses logging.lastResort and logs the message
Output
$ python3 minimal-example.py 1>out 2>err
$
$ cat out
$
$ cat err
2021-09-17 23:58:05,976 mylogger DEBUG - This is a debug message with propagate True
2021-09-17 23:58:05,976 mylogger INFO - This is a info message with propagate True
2021-09-17 23:58:05,976 mylogger WARNING - This is a warning message with propagate True
This is a warning message after propagate is False
$
Why are (A) and (B) logging? Is it because the level on root is completely ignored and only the root's handler is used which is at NOTSET
. In that case, perhaps the flowchart here should be modified.How logging works. I think the language "set current logger to parent" should be skipped (since root is at WARNING and so should skip DEBUG and INFO logs, but doesn't), or am I reading the flowchart incorrectly?
Upvotes: 0
Views: 225
Reputation: 280465
You're reading the flowchart wrong. There's no logger level check once the propagation loop starts. The only logger level check happens at the start, when it checks whether the original logger is enabled for the given level.
Every handler's level is checked when deciding whether to trigger that handler, but the only logger whose level gets checked is the original logger.
Upvotes: 2