简体   繁体   中英

logging.BasicConfig() seems not to follow docs

I think the following code should print all messages but it only works if I call BasicConfig:

import logging

logger = logging.getLogger("log")

# logging.basicConfig(level=logging.DEBUG)  SHOULD NOT BE NEEDED, YET IT IS.

handler = logging.StreamHandler()
handler.setLevel(logging.INFO)
formatter = logging.Formatter("%(levelname)s: %(filename)s(%(lineno)d)[%(name)s]: %(message)s")
handler.setFormatter(formatter)
logger.addHandler(handler)
print("This print test printed")
print(f"Enabled: {logger.isEnabledFor(logging.INFO)}")
logger.propagate = False
logger.debug("This debug printed")
logger.info("This info printed")
logger.warning("This warning printed")
logger.error("This error printed")
logger.critical("This critical printed")

I get that basicConfig controls the root logger, but I'm not using the root logger. Still I am getting this output:

This print test printed
Enabled: False
WARNING: scratch.py(15)[log]: This warning printed
ERROR: scratch.py(16)[log]: This error printed
CRITICAL: scratch.py(17)[log]: This critical printed

Shouldn't the code above had sidestepped the root logger and let my logger work at whatever level I want it to work at?

You are calling the setLevel method of a logging.StreamHandler object. When what you want to be calling is setLevel method of a logging.Logger object.

Changing handler.setLevel(logging.INFO) with logger.setLevel(logging.INFO) will make your code behave as you expect, modulo that it will not print the DEBUG message because you are asking for INFO and above. See (below, I set the level to DEBUG to get all the messages):

>>> import logging
>>> 
>>> logger = logging.getLogger("log")
>>> logger.setLevel(logging.DEBUG)
>>> 
>>> handler = logging.StreamHandler()
>>> formatter = logging.Formatter("%(levelname)s: %(filename)s(%(lineno)d)[%(name)s]: %(message)s")
>>> handler.setFormatter(formatter)
>>> logger.addHandler(handler)
>>> print("This print test printed")
This print test printed
>>> print(f"Enabled: {logger.isEnabledFor(logging.INFO)}")
Enabled: True
>>> logger.propagate = False
>>> logger.debug("This debug printed")
DEBUG: <stdin>(1)[log]: This debug printed
>>> logger.info("This info printed")
INFO: <stdin>(1)[log]: This info printed
>>> logger.warning("This warning printed")
WARNING: <stdin>(1)[log]: This warning printed
>>> logger.error("This error printed")
ERROR: <stdin>(1)[log]: This error printed
>>> logger.critical("This critical printed")
CRITICAL: <stdin>(1)[log]: This critical printed

You may have overlooked in the Logging handlers docs that logging.StreamHandler has a setLevel method (this is the reason why your code does not raise an exception), likely because it it is not explicitly mentioned. logging.StreamHandler is a subclass of logging.Handler (see the code ), and logging.Handler has a setLevel method (see the code or the part of the docs under "Handler Objects" for more details).

For completeness, the reason why your code prints WARNING and above is because it uses the default level, which in this case is 30 , ie, WARNING (you can check this by logger.getEffectiveLevel() ). You may want to refer to the docs under "Logger Objects" to see why that is the case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM