I'm following a basic tutorial on logging in Python, https://docs.python.org/3/howto/logging.html#a-simple-example, and following the steps in an iPython console. As described there, the default level of the root logger is WARNING
:
In [1]: import logging
In [2]: logging.warning('Watch out!')
WARNING:root:Watch out!
In [3]: logging.info('I told you so')
I'd like to explicitly set the level of the root logger to INFO
. I tried doing it using name='root'
, but this has no apparent effect:
In [4]: logging.getLogger('root').setLevel(logging.INFO)
In [5]: logging.info('I told you so')
I am able to set the level of the root logger if I call logging.getLogger()
without arguments:
In [6]: logging.getLogger().setLevel(logging.INFO)
In [7]: logging.info('I told you so')
INFO:root:I told you so
I'm curious, though, why this didn't work the first time? It would seem that this should work since its name
attribute is 'root':
In [12]: root_logger = logging.getLogger()
In [14]: root_logger.name
Out[14]: 'root'
In short, if I didn't want to rely on the default, what name would I pass to logging.getLogger()
in order to get the root logger?
The root logger's name is root
, but you can't access the root logger by name.
Inspecting logging.py reveals this:
def __init__(self, root):
"""
Initialize the manager with the root node of the logger hierarchy.
"""
self.root = root
self.disable = 0
self.emittedNoHandlerWarning = 0
self.loggerDict = {}
root
is stored separately from loggerDict
, which is where all named loggers go.
def getLogger(name=None):
"""
Return a logger with the specified name, creating it if necessary.
If no name is specified, return the root logger.
"""
if name:
return Logger.manager.getLogger(name)
else:
return root
You can follow the manager.getLogger
internal function and find it cannot find root
:
def getLogger(self, name):
"""
Get a logger with the specified name (channel name), creating it
if it doesn't yet exist. If a PlaceHolder existed for the specified
name [i.e. the logger didn't exist but a child of it did], replace
it with the created logger and fix up the parent/child references
which pointed to the placeholder to now point to the logger.
"""
rv = None
_acquireLock()
try:
if self.loggerDict.has_key(name):
rv = self.loggerDict[name]
if isinstance(rv, PlaceHolder):
ph = rv
rv = _loggerClass(name)
rv.manager = self
self.loggerDict[name] = rv
self._fixupChildren(ph, rv)
self._fixupParents(rv)
else:
rv = _loggerClass(name)
rv.manager = self
self.loggerDict[name] = rv
self._fixupParents(rv)
finally:
_releaseLock()
return rv
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With