Note that there are some explanatory texts on larger screens.

plurals
  1. POredirecting sys.stdout to python logging
    text
    copied!<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>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload