Python Log Module: Custom Loggers

I tried to create a custom attribute for logging (caller class name, module name, etc.) and was stuck with a strange exception, indicating that the LogRecord instance created in the process does not have the necessary attributes. After a little 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 gives:

 False False False False True True 

Error or function?

+8
python logging
source share
2 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, the root registrar is created by default when the module is imported. Therefore, every time you look for root looger (passing a false value, such as an empty string), you will get a logging.RootLogger object regardless of any call to logging.setLoggerClass .

As for the log class used, we can see:

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

This means that the global variable contains the log class that will 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 not installed (which will not happen if you did not explicitly set it), the class from the global variable is used.

Therefore, this is a feature. The root log is always a logging.RootLogger object, and other log objects are created based on the configuration at that time.

+5
source share

logging.getLogger() and logging.getLogger("") do not return MyLogger because they return the root logger hierarchy, as described in the logging protocol :

logging.getLogger ([name])

Return the registrar with the specified name or, if no name is specified, return the registrar, which is the root registrar of the hierarchy.

Thus, since you have the logger installed:

 >>> logging.getLogger() <logging.RootLogger object at 0x7d9450> >>> logging.getLogger("foo") <test3.MyLogger object at 0x76d9f0> 

I don’t think this is due to the KeyError with which you started your post. You must post the code that test.py this exception ( test.py ).

+2
source share

All Articles