2010-02-20 75 views

回答

1

不一定是個好主意(它可能會產生混淆看到正常輸出混合!信息和調試消息),但可行的,因爲你可以有多個處理器對象和自定義filter爲他們每個人,爲了挑選和選擇哪些日誌記錄每個處理程序得到處理。

+1

請你能展示(!)如何添加一個合適的過濾器來完成這項工作?下面的gcb的建議意味着「記錄器」仍輸出到stderr,但「ch」輸出相同的東西到標準輸出。鑑於ch是依賴於記錄器,你怎麼能設置一個過濾器記錄器沒有它然後申請也ch?困惑。 – 2014-03-08 11:33:06

6
+0

我想只有在標準輸出的調試和資訊信息,並沒有任何警告或錯誤信息。 – Dinoboff 2010-02-21 21:50:12

+0

文檔已更新,正確的鏈接在http://docs.python.org/library/logging.handlers.html#module-logging.handlers – gcb 2012-02-17 06:13:02

3

從更新文檔的權利,它現在很好地涵蓋了這種情況。

http://docs.python.org/howto/logging.html#logging-advanced-tutorial

import sys # Add this. 
import logging 

# create logger 
logger = logging.getLogger('simple_example') 
logger.setLevel(logging.DEBUG) 

# create console handler and set level to debug 
ch = logging.StreamHandler(sys.__stdout__) # Add this 
ch.setLevel(logging.DEBUG) 

# create formatter 
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') 

# add formatter to ch 
ch.setFormatter(formatter) 

# add ch to logger 
logger.addHandler(ch) 

# 'application' code 
logger.debug('debug message') 
logger.info('info message') 
logger.warn('warn message') 
logger.error('error message') 
logger.critical('critical message') 

我已經上意見從示例所需的兩個變化,使輸出到標準輸出提及。您也可以使用篩選器根據級別進行重定向。

更多信息,瞭解變化是 http://docs.python.org/library/logging.handlers.html#module-logging.handlers

+5

這隻會重定向到stdout,但不會根據stderr的級別進行過濾。 – guettli 2012-03-01 13:43:41

+0

@guettli「你也可以使用過濾器重定向取決於級別」 – gcb 2012-03-09 04:03:34

+2

@gcb請你能展示(!)如何添加一個合適的過濾器來完成這項工作?您的建議意味着「記錄器」仍然輸出到標準錯誤,但「ch」輸出相同的東西到標準輸出。鑑於ch是依賴於記錄器,你怎麼能設置一個過濾器記錄器沒有它然後申請也ch?困惑。 – 2014-03-08 11:31:00

5

我有同樣的問題,並編寫了一個名爲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) 
+0

我知道它有點偏離主題,但是有人可以在字符編碼方面解釋編碼/解碼try/catch邏輯嗎? – Chris 2013-08-20 15:48:03

19
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') 

實施不談,我認爲它是使用python中的日誌記錄工具輸出到終端是一個好主意,特別是因爲您可以添加另一個處理程序來另外登錄到文件。如果將stdout設置爲INFO而不是DEBUG,則甚至可以包含用戶在日誌文件中不會標準查看的其他DEBUG信息。

+0

你從哪裏得到'LessThanFilter'類。無法在Python3庫中找到它。 – buhtz 2015-07-31 08:16:49

+2

我寫了它(並提供了實現),它不在標準庫中。 – 2015-08-25 15:02:08

+0

非常感謝。這是我發現任何人提到默認日誌記錄級別的第一個地方。我爲此失去了一天。一些santiy外觀恢復。謝謝! – penderi 2017-12-07 15:55:55

-1
#!/usr/bin/env python3 
# -*- coding: utf-8 -*- 
import logging 
import sys 

class LessThenFilter(logging.Filter): 
    def __init__(self, level): 
     self._level = level 
     logging.Filter.__init__(self) 

    def filter(self, rec): 
     return rec.levelno < self._level 

log = logging.getLogger() 
log.setLevel(logging.NOTSET) 

sh_out = logging.StreamHandler(stream=sys.stdout) 
sh_out.setLevel(logging.DEBUG) 
sh_out.setFormatter(logging.Formatter('%(levelname)s: %(message)s')) 
sh_out.addFilter(LessThenFilter(logging.WARNING)) 
log.addHandler(sh_out) 

sh_err = logging.StreamHandler(stream=sys.stderr) 
sh_err.setLevel(logging.WARNING) 
sh_err.setFormatter(logging.Formatter('%(levelname)s: %(message)s')) 
log.addHandler(sh_err) 

logging.critical('x') 
logging.error('x') 
logging.warning('x') 
logging.info('x') 
logging.debug('x') 
相關問題