Phyton How can INFO and DEBUG logging message be sent to stdout and higher level message to stderr python logging.info logging.debug,python logging info debug error,

Is there an easy way with python's logging module to send messages with a DEBUG or INFO level and the one with a higher level to different streams?

Is it a good idea anyway?

Answer:1

Not necessarily a good idea (it could be confusing to see info and debug messages mixed in with normal output!), but feasible, since you can have multiple handler objects and a custom filter for each of them, in order to pick and choose which log records each handler gets to handle.

Answer:2
import logging
import sys

class LessThanFilter(logging.Filter):
    def __init__(self, exclusive_maximum, name=""):
        super(LessThanFilter, self).__init__(name)
        self.max_level = exclusive_maximum

    def filter(self, record):
        #non-zero return means we log this message
        return 1 if record.levelno < self.max_level else 0

#Get the root logger
logger = logging.getLogger()
#Have to set the root logger level, it defaults to logging.WARNING
logger.setLevel(logging.NOTSET)

logging_handler_out = logging.StreamHandler(sys.stdout)
logging_handler_out.setLevel(logging.DEBUG)
logging_handler_out.addFilter(LessThanFilter(logging.WARNING))
logger.addHandler(logging_handler_out)

logging_handler_err = logging.StreamHandler(sys.stderr)
logging_handler_err.setLevel(logging.WARNING)
logger.addHandler(logging_handler_err)

#demonstrate the logging levels
logger.debug('DEBUG')
logger.info('INFO')
logger.warning('WARNING')
logger.error('ERROR')
logger.critical('CRITICAL')

Implementation aside, I do think it is a good idea to use the logging facilities in python to output to the terminal, in particular because you can add another handler to additionally log to a file. If you set stdout to be INFO instead of DEBUG, you can even include additional DEBUG information that the user wouldn't standardly see in the log file.

Answer:3

Yes. You must define multiple handlers for your logging.

http://docs.python.org/library/logging.html#logging-to-multiple-destinations

http://docs.python.org/library/logging.handlers.html#module-logging.handlers

Answer:4

I had the same problem and wrote a custom logging handler called SplitStreamHandler:

import sys
import logging

class SplitStreamHandler(logging.Handler):
    def __init__(self):
        logging.Handler.__init__(self)

    def emit(self, record):
        # mostly copy-paste from logging.StreamHandler
        try:
            msg = self.format(record)
            if record.levelno < logging.WARNING:
                stream = sys.stdout
            else:
                stream = sys.stderr
            fs = "%s\n"

            try:
                if (isinstance(msg, unicode) and
                    getattr(stream, 'encoding', None)):
                    ufs = fs.decode(stream.encoding)
                    try:
                        stream.write(ufs % msg)
                    except UnicodeEncodeError:
                        stream.write((ufs % msg).encode(stream.encoding))
                else:
                    stream.write(fs % msg)
            except UnicodeError:
                stream.write(fs % msg.encode("UTF-8"))

            stream.flush()
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            self.handleError(record)
Answer:5

Just for your convenience adding everything together with the formatter in one package:

# shared formatter, but you can use separate ones:
FORMAT = '%(asctime)s - %(name)s - %(levelname)s - %(threadName)s - %(message)s'
formatter = logging.Formatter(FORMAT)

# single app logger:
log = logging.getLogger(__name__)
log.setLevel(logging.INFO)

# 2 handlers for the same logger:
h1 = logging.StreamHandler(sys.stdout)
h1.setLevel(logging.DEBUG)
# filter out everything that is above INFO level (WARN, ERROR, ...)
h1.addFilter(lambda record: record.levelno <= logging.INFO)
h1.setFormatter(formatter)
log.addHandler(h1)

h2 = logging.StreamHandler(sys.stderr)
# take only warnings and error logs
h2.setLevel(logging.WARNING)
h2.setFormatter(formatter)
log.addHandler(h2)

# profit:
log.info(...)
log.debug(...)

My use case was to redirect stdout to a datafile while seeing errors on the screen during processing.

Answer:6



  1. python logging.info logging.debug
  2. python logging info debug error
  3. python logging.basicconfig(levelu003dlogging.debug)
  4. logging.basicconfig(levelu003dlogging.debug
  5. python logging.debug
  6. python logging debug
  7. python logging info debug

I have a postscript file and want it to be printed on a IPP capable device (or CUPS server). What is the minimal code and dependencies I could get away with to do that. Using LPR or libcups gives me ...

I have a postscript file and want it to be printed on a IPP capable device (or CUPS server). What is the minimal code and dependencies I could get away with to do that. Using LPR or libcups gives me ...

I have a problem with serialization of Django inherited models. For example class Animal(models.Model): color = models.CharField(max_length=50) class Dog(Animal): name = models.CharField(...

I have a problem with serialization of Django inherited models. For example class Animal(models.Model): color = models.CharField(max_length=50) class Dog(Animal): name = models.CharField(...