logger.info / logger.ошибка с logger.addHandler-как разделить потоки?

Поэтому я вставляю .infoодин StringIO и .errorдругой StringIO.

Как я могу остановить их от того, чтобы они были помещены в оба?

Вступление:

from __future__ import print_function

import logging

from io import IOBase
from sys import stdout
from platform import python_version_tuple

if python_version_tuple()[0] == '3':
    from IO import StringIO
else:
    try:
        from cStringIO import StringIO
    except ImportError:
        from StringIO import StringIO

Код:

# Some other file, like __init__.py
logging.basicConfig(
      format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s', level='INFO')
handler = logging.root.handlers.pop()
assert logging.root.handlers == [], "root logging handlers aren't empty"
handler.stream.close()
handler.stream = stdout
logging.root.addHandler(handler)
# Some other file, like __init__.py

log = logging.getLogger(__name__)
stderr_stream = logging.StreamHandler(StringIO())
log.addHandler(stderr_stream)
log.setLevel(logging.ERROR)
print('log.level =', {logging.INFO: 'INFO',
                      logging.ERROR: 'ERROR'}[log.level])

stdout_stream = logging.StreamHandler(StringIO())
log.addHandler(stdout_stream)
log.setLevel(logging.INFO)
print('log.level =', {logging.INFO: 'INFO',
                      logging.ERROR: 'ERROR'}[log.level])

log.info('hello')
log.error('world')
print('stderr_stream =', stderr_stream.stream.getvalue())
print('stdout_stream =', stdout_stream.stream.getvalue())

http://ideone.com/Nj6Asz выход:

log.level = ERROR
log.level = INFO
2016-12-23 09:03:27,761 __main__     INFO     hello
2016-12-23 09:03:27,761 __main__     ERROR    world
stderr_stream = hello
world

stdout_stream = hello
world

1 ответ

  1. Это может быть достигнуто с помощью фильтра . Так как функция фильтра является произвольной булевой функцией (которая по какой-то причине возвращает ноль/ненулевое значение), вы можете использовать ее для фильтрации уровня для минимума и максимума:

    class LevelRangeFilter:
        def __init__(self, min_level, max_level):
            self._min_level = min_level
            self._max_level = max_level
    
        def filter(self, record):
            if (
                (self._min_level is None or self._min_level <= record.levelno)
                and
                (self._max_level is None or record.levelno < self._max_level)
            ):
                return 0
            else:
                return 1
    

    stderr_stream.addFilter(LevelRangeFilter(logging.ERROR, None))
    stdout_stream.addFilter(LevelRangeFilter(logging.INFO, logging.ERROR))