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) *  |
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) *  |
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) *  |
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) *  |
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) *  |
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) *  |
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. |
|
|