In this case, your 'child_logger' is your root logger. If you had initialized it like so:
logger = getLogger('root')
child_logger = getLogger('root.child')
child_logger
is a child of logger
as defined by:
The name is potentially a period-separated hierarchical value, like foo.bar.baz (though it could also be just plain foo, for example). Loggers that are further down in the hierarchical list are children of loggers higher up in the list. For example, given a logger with a name of foo, loggers with names of foo.bar, foo.bar.baz, and foo.bam are all descendants of foo. The logger name hierarchy is analogous to the Python package hierarchy, and identical to it if you organise your loggers on a per-module basis using the recommended construction logging.getLogger(__name__
). That’s because in a module, __name__
is the module’s name in the Python package namespace.
If you do not want a child to propogate, you can set logger.propagate
= False
.
Furthermore, if you would like only certain levels written to your child logger file (i.e. only debug) but you want higher level to still propagate, you could create a subclass of a handler, as in mine here:
from logging import DEBUG, INFO, WARN, ERROR, CRITICAL, handlers
class DebugRotatingFileHandler(handlers.RotatingFileHandler):
def __init__(self, filename, mode, maxBytes, backupCount, encoding, delay):
super(DebugRotatingFileHandler, self).__init__(
self, filename, mode, maxBytes, backupCount, encoding, delay)
def emit(self, record):
if record.levelno != DEBUG:
return
super(DebugRotatingFileHandler, self).emit(self, record)
(Yes, I know there are some improvements that can be made, this is old code.)
For example, executing debug_logger.info("Info Message")
would print nothing to the debug_logger's specified file, however, if root_logger
's level was set to info, or debug, it would print it out in it's file. I use this for debug logging, whilst still retaining the ability to have the logger make error message calls and print those to the root log.