2016-12-26 42 views
0

所以我把.info放在一個StringIO中,.error放在另一個StringIO中。logger.info/logger.error與logger.addHandler - 如何拆分流?

我該如何阻止它們同時進入兩者?

前奏:

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 
+0

注你正在設置* logger *的級別,而不是單個的處理程序。你可能想看看。 – aib

+0

@aib:但我正在設置各個處理程序的級別? –

回答

0

這可以通過使用一個Filter來實現。由於過濾器的功能是任意布爾函數(返回零/非零出於某種原因)你可以把它過濾的最低水平,最大:

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)) 
+0

謝謝,這有效!採取你的方法,我壓縮了'filter'函數並添加了'logging.Filter'的子類:http://ideone.com/IjG471 - 歡迎您編輯以反映這一點。 –