【问题标题】:How to use multi logger in Python如何在 Python 中使用多记录器
【发布时间】:2020-10-15 10:34:10
【问题描述】:

我尝试使用两个不同的记录器来处理不同的日志级别。例如,我希望将信息消息存储在文件中并且不记录错误消息。一些特殊功能的错误信息将通过电子邮件发送给用户。

我编写了一个简单的程序来测试日志记录模块。

代码:

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")

输出: Output result

我可以看到他们的级别是正确的,但他们都表现得像级别是错误的。

如何正确配置它们?

回答:根据蓝调的建议,我添加了一个处理程序,它解决了我的问题。 这是修改后的代码:

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")

【问题讨论】:

    标签: python logging python-logging


    【解决方案1】:

    def_logger 及其任何父级都没有附加处理程序。所以发生的事情是日志模块回退到logging.lastResort,默认情况下是一个带有警告级别的StreamHandler。这就是为什么信息消息没有出现,而错误却出现的原因。因此,要解决您的问题,请将处理程序附加到 def_logger。

    注意:在您的场景中,两个记录器的唯一父级是默认的根处理程序。

    【讨论】:

    • 这对我来说很清楚。好像我误解了处理程序和记录器的概念。
    【解决方案2】:

    您可以为每个记录器或处理程序添加 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,则处理日志记录。否则跳过。

    注意:

    • 附加到logger 的过滤器不会被后代记录器生成的日志记录调用。例如,如果您向记录器A 添加过滤器,则不会为记录器A.BA.B.C 生成的记录调用它。

    • 附加到handler 的过滤器会在该处理程序发出事件之前进行咨询。

    这意味着您只需要一个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")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-09
      • 1970-01-01
      • 2013-03-24
      • 1970-01-01
      • 2021-12-22
      • 2017-02-07
      • 2014-04-09
      相关资源
      最近更新 更多