title: How to extend the logging.Logger Class?
body: <p>I would like to start with a basic logging class that inherits from Python's <code>logging.Logger</code> class. However, I am not sure about how I should be constructing my class so that I can establish the basics needed for customising the inherited logger.</p>
  <p>This is what I have so far in my <code>logger.py</code> file:</p>
  <pre><code>import sys
  import logging
  from logging import DEBUG, INFO, ERROR
  
  class MyLogger(object):
      def __init__(self, name, format=&quot;%(asctime)s | %(levelname)s | %(message)s&quot;, level=INFO):
          # Initial construct.
          self.format = format
          self.level = level
          self.name = name
  
          # Logger configuration.
          self.console_formatter = logging.Formatter(self.format)
          self.console_logger = logging.StreamHandler(sys.stdout)
          self.console_logger.setFormatter(self.console_formatter)
  
          # Complete logging config.
          self.logger = logging.getLogger(&quot;myApp&quot;)
          self.logger.setLevel(self.level)
          self.logger.addHandler(self.console_logger)
  
      def info(self, msg, extra=None):
          self.logger.info(msg, extra=extra)
  
      def error(self, msg, extra=None):
          self.logger.error(msg, extra=extra)
  
      def debug(self, msg, extra=None):
          self.logger.debug(msg, extra=extra)
  
      def warn(self, msg, extra=None):
          self.logger.warn(msg, extra=extra)
  </code></pre>
  <p>This is the main <code>myApp.py</code>:</p>
  <pre><code>import entity
  from core import MyLogger
  
  my_logger = MyLogger(&quot;myApp&quot;)
  
  def cmd():
      my_logger.info(&quot;Hello from %s!&quot; % (&quot;__CMD&quot;))
  
  entity.third_party()
  entity.another_function()
  cmd()
  </code></pre>
  <p>And this is the <code>entity.py</code> module:</p>
  <pre><code># Local modules
  from core import MyLogger
  
  # Global modules
  import logging
  from logging import DEBUG, INFO, ERROR, CRITICAL
  
  my_logger = MyLogger(&quot;myApp.entity&quot;, level=DEBUG)
  
  def third_party():
      my_logger.info(&quot;Initial message from: %s!&quot; % (&quot;__THIRD_PARTY&quot;))
  
  def another_function():
      my_logger.warn(&quot;Message from: %s&quot; % (&quot;__ANOTHER_FUNCTION&quot;))
  </code></pre>
  <p>When I run the main app, I get this:</p>
  <pre><code>2016-09-14 12:40:50,445 | INFO | Initial message from: __THIRD_PARTY!
  2016-09-14 12:40:50,445 | INFO | Initial message from: __THIRD_PARTY!
  2016-09-14 12:40:50,445 | WARNING | Message from: __ANOTHER_FUNCTION
  2016-09-14 12:40:50,445 | WARNING | Message from: __ANOTHER_FUNCTION
  2016-09-14 12:40:50,445 | INFO | Hello from __CMD!
  2016-09-14 12:40:50,445 | INFO | Hello from __CMD!
  </code></pre>
  <p>Everything is printed twice, as probably I have failed to set the logger class properly.</p>
  <h2>Update 1</h2>
  <p>Let me clarify my goals.</p>
  <p><strong>(1)</strong> I would like to encapsulate the main logging functionality in one single location so I can do this:</p>
  <pre><code> from mylogger import MyLogger
   my_logger = MyLogger(&quot;myApp&quot;)
   my_logger.info(&quot;Hello from %s!&quot; % (&quot;__CMD&quot;))
  </code></pre>
  <p><strong>(2)</strong> I am planning to use <code>CustomFormatter</code> and <code>CustomAdapter</code> classes. This bit does not require a custom logging class, those can be plugged in straight away.</p>
  <p><strong>(3)</strong> I probably do not need to go very deep in terms of customisation of the underlying logger class (records etc.), intercepting <code>logger.info</code>, <code>loggin.debug</code> etc. should be enough.</p>
  <p>So referring back to <a href="http://code.activestate.com/recipes/474089-extending-the-logging-module/" rel="noreferrer">this python receipt</a> that has been circulated many times on these forums:</p>
  <p>I am trying to the find the sweet point between having a <code>Logger Class</code>, yet still be able to use the built in functions like assigning <code>Formatters</code> and <code>Adapters</code> etc. So everything stays compatible with the <code>logging</code> module.</p>
  <pre><code>class OurLogger(logging.getLoggerClass()):
      def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None):
          # Don't pass all makeRecord args to OurLogRecord bc it doesn't expect &quot;extra&quot;
          rv = OurLogRecord(name, level, fn, lno, msg, args, exc_info, func)
          # Handle the new extra parameter.
          # This if block was copied from Logger.makeRecord
          if extra:
              for key in extra:
                  if (key in [&quot;message&quot;, &quot;asctime&quot;]) or (key in rv.__dict__):
                      raise KeyError(&quot;Attempt to overwrite %r in LogRecord&quot; % key)
                  rv.__dict__[key] = extra[key]
          return rv
  </code></pre>
  <h2>Update 2</h2>
  <p>I have created a repo with a simple python app demonstrating a possible solution. However, I am keen to improve this.</p>
  <p><a href="https://github.com/symbolix/xlog_example" rel="noreferrer">xlog_example</a></p>
  <p>This example effectively demonstrates the technique of overriding the <code>logging.Logger</code> class and the <code>logging.LogRecord</code> class through inheritance.</p>
  <p>Two external items are mixed into the log stream: <code>funcname</code> and <code>username</code> without using any <code>Formatters</code> or <code>Adapters</code>.</p>