Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Logging module: custom loggers

Tags:

python

logging

I was trying to create a custom attribute for logging (caller's class name, module name, etc.) and got stuck with a strange exception telling me that the LogRecord instance created in the process did not have the necessary attributes. After a bit of testing I ended up with this:

import logging

class MyLogger(logging.getLoggerClass()):
    value = None

logging.setLoggerClass(MyLogger)

loggers = [
    logging.getLogger(),
    logging.getLogger(""),
    logging.getLogger("Name")
]

for logger in loggers:
    print(isinstance(logger, MyLogger), hasattr(logger, "value"))

This seemingly correct piece of code yields:

False False
False False
True True

Bug or feature?

like image 350
Pastafarianist Avatar asked Feb 16 '12 18:02

Pastafarianist


1 Answers

Looking at the source code we can see the following:

root = RootLogger(WARNING)
def getLogger(name=None):
    if name:
        return Logger.manager.getLogger(name)
    else:
        return root

That is, a root logger is created by default when the module is imported. Hence, every time you look for the root looger (passing a false value such as the empty string), you're going to get a logging.RootLogger object regardless of any call to logging.setLoggerClass.

Regarding the logger class being used we can see:

_loggerClass = None
def setLoggerClass(klass):
    ...
    _loggerClass = klass

This means that a global variable holds the logger class to be used in the future.

In addition to this, looking at logging.Manager (used by logging.getLogger), we can see this:

def getLogger(self, name):
    ...
            rv = (self.loggerClass or _loggerClass)(name)

That is, if self.loggerClass isn't set (which won't be unless you've explicitly set it), the class from the global variable is used.

Hence, it's a feature. The root logger is always a logging.RootLogger object and the other logger objects are created based on the configuration at that time.

like image 63
jcollado Avatar answered Oct 06 '22 00:10

jcollado