问题描述
我尝试使用两种不同的记录器来处理不同的日志级别。例如,我希望信息消息存储在文件中,并且不记录错误消息。某些特殊功能的错误消息将通过电子邮件发送给用户。
我编写了一个简单的程序来测试日志记录模块。
代码:
import logging
def_logger = logging.getLogger("debuglogger")
def_logger.setLevel(logging.DEBUG)
maillogger = logging.getLogger("mail")
maillogger.setLevel(logging.ERROR)
mailhandler = logging.StreamHandler()
mailhandler.setLevel(logging.ERROR)
mailhandler.setFormatter(logging.Formatter('Error: %(asctime)s - %(name)s - %(levelname)s - %(message)s'))
maillogger.addHandler(mailhandler)
print(def_logger.getEffectiveLevel())
print(maillogger.getEffectiveLevel())
def_logger.info("info 1")
maillogger.info("info 2")
def_logger.error("error 1")
maillogger.error("error 2")
我可以看到它们的级别是正确的,但是它们的行为都像是ERROR。
如何正确配置它们?
答案:根据布鲁斯的建议,我添加了一个处理程序,它解决了我的问题。 这是修改后的代码:
import logging
def_logger = logging.getLogger("debuglogger")
def_logger.setLevel(logging.DEBUG)
def_logger.addHandler(logging.StreamHandler()) #added a handler here
maillogger = logging.getLogger("mail")
maillogger.setLevel(logging.ERROR)
mailhandler = logging.StreamHandler()
mailhandler.setLevel(logging.ERROR)
mailhandler.setFormatter(logging.Formatter('Error: %(asctime)s - %(name)s - %(levelname)s - %(message)s'))
maillogger.addHandler(mailhandler)
print(def_logger.getEffectiveLevel())
print(maillogger.getEffectiveLevel())
def_logger.info("info 1")
maillogger.info("info 2")
def_logger.error("error 1")
maillogger.error("error 2")
解决方法
def_logger及其任何父母均未附加处理程序。因此,发生的情况是日志记录模块回退到logging.lastResort
,默认情况下,该模块是级别为Warning的StreamHandler。这就是为什么信息消息没有出现而错误消息却出现的原因。因此,要解决您的问题,请将处理程序附加到def_logger。
注意:在您的方案中,两个记录器唯一拥有的父级是默认的根处理程序。
,您可以为每个记录器或处理程序添加一个filter
以仅处理感兴趣的记录
import logging
def filter_info(record):
return True if record.levelno == logging.INFO else False
def filter_error(record):
return True if record.levelno >= logging.ERROR else False
# define debug logger
def_logger = logging.getLogger("debuglogger")
def_logger.setLevel(logging.DEBUG)
def_logger.addFilter(filter_info) # add filter directly to this logger since you didn't define any handler
# define handler for mail logger
mail_handler = logging.StreamHandler()
mail_handler.setLevel(logging.ERROR)
mail_handler.setFormatter(logging.Formatter('Error: %(asctime)s - %(name)s - %(levelname)s - %(message)s'))
mail_handler.addFilter(filter_error) # add filter to handler
mail_logger = logging.getLogger("mail")
mail_logger.setLevel(logging.ERROR)
mail_logger.addHandler(mail_handler)
# test
def_logger.info("info 1")
mail_logger.info("info 2")
def_logger.error("error 1")
mail_logger.error("error 2")
如果filter
返回True
,则处理日志记录。否则,它将被跳过。
注意:
-
由后代记录器生成的日志记录不会调用附加到
-
过滤器。例如,如果您向记录器
A
添加过滤器,则记录器A.B
或A.B.C
生成的记录都不会调用该过滤器。
在该处理程序发出事件之前,请先咨询 -
附加到
handler
的过滤器。
logger
的这意味着您只需要一个logger
并添加两个handler
,并附加了不同的过滤器即可。
import logging
def filter_info(record):
return True if record.levelno == logging.INFO else False
def filter_error(record):
return True if record.levelno >= logging.ERROR else False
# define your logger
logger = logging.getLogger("myapp")
logger.setLevel(logging.DEBUG)
# define handler for file
file_handler = logging.FileHandler('path_to_log.txt')
file_handler.level = logging.INFO
file_handler.addFilter(filter_info) # add filter to handler
# define handler for mail
mail_handler = logging.StreamHandler()
mail_handler.setLevel(logging.ERROR)
mail_handler.setFormatter(logging.Formatter('Error: %(asctime)s - %(name)s - %(levelname)s - %(message)s'))
mail_handler.addFilter(filter_error) # add filter to handler
logger.addHandler(file_handler)
logger.addHandler(mail_handler)
# test
logger.info("info 1")
logger.info("info 2")
logger.error("error 1")
logger.error("error 2")