YaOg
YaOg

Reputation: 1768

python logs to both stdout and stderr

I am using python logging like this:

logging.basicConfig(stream=sys.stdout, level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
log = logging.getLogger()

Everything works fine. only issue is that all log messages are printed to both stdout and stderr. stdout is formatted as I expect. stderr simply prints the message itself in error stream.

I see that log.handlers indeed contains 2 handlers. Removing the stderr one doesn't seem to have effect. Tried something like this:

for handler in log.handlers:
    if handler.stream and handler.stream.name == '<stderr>':
        log.handlers.remove(handler)

Any way around this issue?

Upvotes: 1

Views: 2101

Answers (1)

Green
Green

Reputation: 2565

You can use logging.StreamHandler()

like that:

logging.basicConfig(handlers=[logging.StreamHandler()], level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
log = logging.getLogger()

If you also want to that certain level would go stderr (only Error or Error and Warning) and other stdout. you can do something like suggested here by @crosswired:

logger = logging.getLogger("__name__")
logger.setLevel(logging.DEBUG)
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
formatter = logging.Formatter(format)

h1 = logging.StreamHandler(sys.stdout)
h1.setLevel(logging.DEBUG)
h1.addFilter(lambda record: record.levelno <= logging.INFO)
h1.setFormatter(formatter)

h2 = logging.StreamHandler()
h2.setLevel(logging.WARNING)
h2.setFormatter(formatter)
logger.addHandler(h1)
logger.addHandler(h2)
logger.info("info")
logger.error("error")

output

Python logging split between stdout and stderr

Upvotes: 3

Related Questions