python的日誌記錄模塊是否有一種簡單的方式將消息的DEBUG或INFO級別和具有更高級別的消息發送到不同的流?如何將INFO和DEBUG日誌消息發送到stdout和更高級別的消息到stderr
無論如何,這是一個好主意嗎?
python的日誌記錄模塊是否有一種簡單的方式將消息的DEBUG或INFO級別和具有更高級別的消息發送到不同的流?如何將INFO和DEBUG日誌消息發送到stdout和更高級別的消息到stderr
無論如何,這是一個好主意嗎?
不一定是個好主意(它可能會產生混淆看到正常輸出混合!信息和調試消息),但可行的,因爲你可以有多個處理器對象和自定義filter爲他們每個人,爲了挑選和選擇哪些日誌記錄每個處理程序得到處理。
請你能展示(!)如何添加一個合適的過濾器來完成這項工作?下面的gcb的建議意味着「記錄器」仍輸出到stderr,但「ch」輸出相同的東西到標準輸出。鑑於ch是依賴於記錄器,你怎麼能設置一個過濾器記錄器沒有它然後申請也ch?困惑。 – 2014-03-08 11:33:06
從更新文檔的權利,它現在很好地涵蓋了這種情況。
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
我有同樣的問題,並編寫了一個名爲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)
我知道它有點偏離主題,但是有人可以在字符編碼方面解釋編碼/解碼try/catch邏輯嗎? – Chris 2013-08-20 15:48:03
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信息。
#!/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')
請參閱本的解決方案:http://stackoverflow.com/questions/1383254/logging-streamhandler-and-standard-streams – guettli 2012-03-01 13:42:21