title: Subclassing logging.Logger to add own functionality
body: <p>I'm writing code for a robotic system that needs to log to different places, depending on type of deployment/time during startup/...</p>
  <p>I'd like to have an option to create a basic logger, then add handlers when appropriate.</p>
  <p>I have a basic function in place to create a streamhandler:</p>
  <pre><code>def setup_logger() -&gt; logging.Logger:
      &quot;&quot;&quot;Setup logging.
      Returns logger object with (at least) 1 streamhandler to stdout.
  
      Returns:
          logging.Logger: configured logger object
      &quot;&quot;&quot;
      logger = logging.getLogger()
      logger.setLevel(logging.DEBUG)
      stream_handler = logging.StreamHandler()  # handler to stdout
      stream_handler.setLevel(logging.ERROR)
      stream_handler.setFormatter(MilliSecondsFormatter(LOG_FMT))
      logger.addHandler(stream_handler)
      return logger
  </code></pre>
  <p>When the system has internet access, I'd like to add a mail handler (separate class, subclassed from logging.handlers.BufferingHandler).
  (Example below with a simple rotating file handler to simplify)</p>
  <pre><code>def add_rotating_file(logger: logging.Logger) -&gt; logging.Logger:
      rot_fil_handler = logging.handlers.RotatingFileHandler(LOGFILE,
                                                             maxBytes=LOGMAXBYTES,
                                                             backupCount=3)
      rot_fil_handler.setLevel(logging.DEBUG)
      rot_fil_handler.setFormatter(MilliSecondsFormatter(LOG_FMT))
      logger.addHandler(rot_fil_handler)
      return logger
  </code></pre>
  <p>Usage would be:</p>
  <pre><code>logger = setup_logger()
  logger = add_rotating_file(logger)
  </code></pre>
  <p>This looks &quot;wrong&quot; to me. Giving the logger to the function as an argument and then returning it seems weird and I would think I would better create a class, subclassing logging.Logger.</p>
  <p>So something like this:</p>
  <pre><code>class pLogger(logging.Logger):
  
      def __init__(self):
          super().__init__()
          self._basic_configuration()
  
      def _basic_configuration(self):
          self.setLevel(logging.DEBUG)
          stream_handler = logging.StreamHandler()  # handler to stdout
          stream_handler.setLevel(logging.ERROR)
          stream_handler.setFormatter(MilliSecondsFormatter(LOG_FMT))
          self.addHandler(stream_handler)
  
      def add_rotating_handler(self):
          rot_file_handler = logging.handlers.RotatingFileHandler(LOGFILE,
                                                              maxBytes=LOGMAXBYTES,
                                                              backupCount=3)
          self.addHandler(rot_file_handler)
  
                                                  
  </code></pre>
  <p>However, the super().<strong>init</strong>() function needs the logger name as an argument and -as far as I know-, the root logger should be created using logging.getLogger(), so without a name.</p>
  <p>Another way would be to <em>not</em> subclass anything, but create a self.logger in my class, which seems wrong as well.</p>
  <p>I found <a href="https://stackoverflow.com/questions/66540452/pattern-to-subclass-logging-logger">this stackexchange question</a> which seems related but I can't figure out how to interpret the answer.</p>
  <p>What's the &quot;correct&quot; way to do this?</p>