Naming loggers

There are four common use cases for using logging.getLogger() to name our Loggers. We often pick names to parallel our application's architecture, as described in the following examples:

  • Module names: We might have a module global Logger instance for modules that contain a large number of small functions or classes for which a large number of objects are created. When we extend tuple, for example, we don't want a reference to Logger in each instance. We'll often do this globally, and usually close to the front of the module, as follows:
import logging 
logger = logging.getLogger(__name__) 
  • Object instances: This was shown previously, when we created Logger in the __init__() method. This Logger will be unique to the instance; using only a qualified class name might be misleading, because there will be multiple instances of the class. A better design is to include a unique instance identifier in the logger's name, as follows:
def __init__(self, player_name) 
    self.name = player_name 
    self.logger = logging.getLogger(
f"{self.__class__.__qualname__}.{player_name}")
  • Class names: This was shown previously, when we defined a simple decorator. We can use __class__.__qualname__ as the Logger name and assign Logger to the class as a whole. It will be shared by all instances of the class.
  • Function names: For small functions that are used frequently, we'll often use a module-level log, as shown previously. For larger functions that are rarely used, we might create a log within the function, as follows:
def main(): 
    log = logging.getLogger("main") 

The idea here is to be sure that our Logger names match the names of components in our software architecture. This provides us with the most transparent logging, simplifying debugging.

In some cases, however, we might have a more complex collection of Loggers. We might have several distinct types of informational messages from a class. Two common examples are financial audit logs and security access logs. We might want several parallel hierarchies of Loggers; one with names that start with audit. and another with names that start with security. A class might have more specialized Loggers, with names such as audit.module.Class or security.module.Class, as shown in the following example:

self.audit_log = logging.getLogger(
f"audit.{self.__class__.__qualname__}")

Having multiple logger objects available in a class allows us to finely control the kinds of output. We can configure each Logger to have different handlers. We'll use the more advanced configurations in the following section to direct the output to different destinations.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset