如何将INFO和DEBUG日志信息发送到stdout,而将更高等级的信息发送到stderr
有没有简单的方法可以用Python的日志模块,把DEBUG或INFO级别的信息和更高级别的信息发送到不同的地方?
这样做是否合理呢?
9 个回答
7
为了方便起见,这里把所有内容都放在一个包里,使用格式化工具:
# shared formatter, but you can use separate ones:
FORMAT = '%(asctime)s - %(name)s - %(levelname)s - %(threadName)s - %(message)s'
formatter = logging.Formatter(FORMAT)
# single app logger:
log = logging.getLogger(__name__)
log.setLevel(logging.INFO)
# 2 handlers for the same logger:
h1 = logging.StreamHandler(sys.stdout)
h1.setLevel(logging.DEBUG)
# filter out everything that is above INFO level (WARN, ERROR, ...)
h1.addFilter(lambda record: record.levelno <= logging.INFO)
h1.setFormatter(formatter)
log.addHandler(h1)
h2 = logging.StreamHandler(sys.stderr)
# take only warnings and error logs
h2.setLevel(logging.WARNING)
h2.setFormatter(formatter)
log.addHandler(h2)
# profit:
log.info(...)
log.debug(...)
我的需求是把标准输出(也就是程序正常运行时的输出)重定向到一个数据文件里,同时在处理过程中能在屏幕上看到错误信息。
42
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中使用日志功能来输出信息到终端是个好主意。特别是你可以添加一个额外的处理器,把日志信息也记录到一个文件里。如果你把标准输出的级别设置为INFO而不是DEBUG,那么你甚至可以在日志文件中包含一些用户通常看不到的额外DEBUG信息。
-4
这不一定是个好主意(因为把信息和调试消息混在正常输出里可能会让人感到困惑!),不过是可行的。你可以有多个处理器对象,并为每个处理器设置一个自定义的过滤器,这样就可以选择每个处理器要处理哪些日志记录。