title: redirecting sys.stdout to python logging
body: <p>So right now we have a lot of python scripts and we are trying to consolidate them and fix and redundancies. One of the things we are trying to do, is to ensure that all sys.stdout/sys.stderr goes into the python logging module.</p>
  
  <p>Now the main thing is, we want the following printed out: </p>
  
  <pre><code>[&lt;ERROR LEVEL&gt;] | &lt;TIME&gt; | &lt;WHERE&gt; | &lt;MSG&gt;
  </code></pre>
  
  <p>Now all sys.stdout / sys.stderr msgs pretty much in all of the python error messages are in the format of [LEVEL] - MSG, which are all written using sys.stdout/sys.stderr. I can parse the  fine, in my sys.stdout  wrapper and in the sys.stderr wrapper. Then call the corresponding logging level, depending on the parsed input.</p>
  
  <p>So basically we have a package called foo, and a subpackage called log. In <code>__init__.py</code> we define the following:</p>
  
  <pre><code>def initLogging(default_level = logging.INFO, stdout_wrapper = None, \
                  stderr_wrapper = None):
      """
          Initialize the default logging sub system
      """
      root_logger = logging.getLogger('')
      strm_out = logging.StreamHandler(sys.__stdout__)
      strm_out.setFormatter(logging.Formatter(DEFAULT_LOG_TIME_FORMAT, \
                                              DEFAULT_LOG_TIME_FORMAT))
      root_logger.setLevel(default_level)
      root_logger.addHandler(strm_out)
  
      console_logger = logging.getLogger(LOGGER_CONSOLE)
      strm_out = logging.StreamHandler(sys.__stdout__)
      #strm_out.setFormatter(logging.Formatter(DEFAULT_LOG_MSG_FORMAT, \
      #                                        DEFAULT_LOG_TIME_FORMAT))
      console_logger.setLevel(logging.INFO)
      console_logger.addHandler(strm_out)
  
      if stdout_wrapper:
          sys.stdout = stdout_wrapper
      if stderr_wrapper:
          sys.stderr = stderr_wrapper
  
  
  def cleanMsg(msg, is_stderr = False):
      logy = logging.getLogger('MSG')
      msg = msg.rstrip('\n').lstrip('\n')
      p_level = r'^(\s+)?\[(?P&lt;LEVEL&gt;\w+)\](\s+)?(?P&lt;MSG&gt;.*)$'
      m = re.match(p_level, msg)
      if m:
          msg = m.group('MSG')
          if m.group('LEVEL') in ('WARNING'):
              logy.warning(msg)
              return
          elif m.group('LEVEL') in ('ERROR'):
              logy.error(msg)
              return
      if is_stderr:
          logy.error(msg)
      else:
          logy.info(msg)
  
  class StdOutWrapper:
      """
          Call wrapper for stdout
      """
      def write(self, s):
          cleanMsg(s, False)
  
  class StdErrWrapper:
      """
          Call wrapper for stderr
      """
      def write(self, s):
          cleanMsg(s, True)
  </code></pre>
  
  <p>Now we would call this in one of our scripts for example:</p>
  
  <pre><code>import foo.log
  foo.log.initLogging(20, foo.log.StdOutWrapper(), foo.log.StdErrWrapper())
  sys.stdout.write('[ERROR] Foobar blew')
  </code></pre>
  
  <p>Which would be converted into an error log message. Like:</p>
  
  <pre><code>[ERROR] | 20090610 083215 | __init__.py | Foobar Blew
  </code></pre>
  
  <p>Now the problem is when we do that, The module where the error message was logged is now the <code>__init__</code> (corresponding to <code>foo.log.__init__.py</code> file) which defeats the whole purpose.</p>
  
  <p>I tried doing a deepCopy/shallowCopy of the stderr/stdout objects, but that does nothing, it still says the module the message occured in <code>__init__.py</code>. How can i make it so this doesn't happen?</p>