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.