Issue 30862: parent logger should also check the level (original) (raw)

Created on 2017-07-06 01:06 by qingyunha, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 2604 merged vinay.sajip,2017-07-06 16:45
Messages (10)
msg297791 - (view) Author: TaoQingyun (qingyunha) * Date: 2017-07-06 01:11
``` import logging logging.basicConfig(level=logging.ERROR) l = logging.getLogger("test") l.setLevel(logging.DEBUG) l.debug("Hello world") ``` it will print 'Hello world'
msg297799 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2017-07-06 04:19
I will let Vinay answer definitively, but this is working as designed. This allows you to set 'debug' level on a sub-logger without getting debug output for every logger in your system, which is what you would get otherwise as the default logging level is NOTSET. The documentation for setLevel could probably be improved slightly in this regard, as currently you have to infer this behavior from the fact that NOTSET causes the ancestor logger's level to be used, implying that if you set it, that setting is used and not the ancestor logger's level.
msg297810 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2017-07-06 07:10
As RDM says, this behaviour is as designed. The logger's setLevel documentation says: "Sets the threshold for this logger to lvl. Logging messages which are less severe than lvl will be ignored. When a logger is created, the level is set to NOTSET (which causes all messages to be processed when the logger is the root logger, or delegation to the parent when the logger is a non-root logger). Note that the root logger is created with level WARNING. The term ‘delegation to the parent’ means that if a logger has a level of NOTSET, its chain of ancestor loggers is traversed until either an ancestor with a level other than NOTSET is found, or the root is reached. If an ancestor is found with a level other than NOTSET, then that ancestor’s level is treated as the effective level of the logger where the ancestor search began, and is used to determine how a logging event is handled. If the root is reached, and it has a level of NOTSET, then all messages will be processed. Otherwise, the root’s level will be used as the effective level." Not sure how I can improve upon that, as it seems clear enough, but any suggestions are welcome.
msg297814 - (view) Author: TaoQingyun (qingyunha) * Date: 2017-07-06 08:17
yes, I understand the effective level. my question is that before call ancestor's handler, should also check `c.isEnabledFor(record.levelno)` ``` def callHandlers(self, record): """ Pass a record to all relevant handlers. Loop through all handlers for this logger and its parents in the logger hierarchy. If no handler was found, output a one-off error message to sys.stderr. Stop searching up the hierarchy whenever a logger with the "propagate" attribute set to zero is found - that will be the last logger whose handlers are called. """ c = self found = 0 while c: for hdlr in c.handlers: found = found + 1 if record.levelno >= hdlr.level: hdlr.handle(record) if not c.propagate: c = None #break out else: c = c.parent ... ```
msg297830 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2017-07-06 13:58
@qingyunha: we are telling you that that would *introduce* a bug. This is working the way it is supposed to. Vinay, what if we rewrote the beginning of that paragraph like this: Sets the threshold for this logger to lvl. Logging messages which are less severe than lvl will be ignored, logging messages which have severity lvl or higher will be emitted by whichever handler or handlers service this logger, unless the handler's level has been set to a higher severity level than lvl. When a logger is created, the level is set to NOTSET....
msg297834 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2017-07-06 16:51
New changeset 0653fba51c03d20fa4381ba0836acd17fd05b04b by Vinay Sajip in branch 'master': bpo-30862: Updated Logger.setLevel documentation. (GH-2604) https://github.com/python/cpython/commit/0653fba51c03d20fa4381ba0836acd17fd05b04b
msg307535 - (view) Author: TaoQingyun (qingyunha) * Date: 2017-12-04 03:11
Maybe I misunderstand. At least the basicConfig should also set the level of the handler that it created.
msg307765 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2017-12-06 19:30
> Maybe I misunderstand. I think you do misunderstand. The level of the handler created by basicConfig doesn't have any level set, so it will process any message it is asked to handle. This is working as designed.
msg307787 - (view) Author: TaoQingyun (qingyunha) * Date: 2017-12-07 03:54
Sorry to disturb. When calling `logging.basicConfig(level=logging.ERROR)`, I expect only the ERROR or above level will be logged. so the level argument if set should also pass to the handler.
msg307818 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2017-12-07 16:41
basicConfig() provides default behaviour for simple cases. If you don't like the defaults it provides, you can choose your own configuration code to do exactly what you want.
History
Date User Action Args
2022-04-11 14:58:48 admin set github: 75045
2017-12-07 16:41:19 vinay.sajip set messages: +
2017-12-07 03:54:04 qingyunha set messages: +
2017-12-06 19:30:01 vinay.sajip set messages: +
2017-12-04 03:11:49 qingyunha set messages: +
2017-07-06 16:51:30 vinay.sajip set messages: +
2017-07-06 16:45:53 vinay.sajip set pull_requests: + <pull%5Frequest2672>
2017-07-06 13:58:43 r.david.murray set messages: +
2017-07-06 08:17:15 qingyunha set messages: +
2017-07-06 07:10:11 vinay.sajip set status: open -> closedresolution: not a bugmessages: + stage: resolved
2017-07-06 04:19:59 r.david.murray set nosy: + r.david.murraymessages: +
2017-07-06 04:00:32 ned.deily set nosy: + vinay.sajip
2017-07-06 01:11:03 qingyunha set messages: +
2017-07-06 01:06:28 qingyunha create