【问题标题】:Duplicate messages from a class logger来自类记录器的重复消息
【发布时间】:2019-04-21 04:45:17
【问题描述】:

我的类构造了一个以 init() 中的类命名的记录器。现在,当我记录一条消息时,我会为迄今为止创建的每个类实例获得一份消息副本。如何避免这种重复?

我还担心这可能只是一个更深层次问题的症状 - 在一次可能实例化几百个类的应用程序中,这是一种浪费内存管理的方法吗?是否有更明智的方式来处理跨多个类的日志记录?

虽然下面的代码是对问题的简单再现,但实际代码是非常模块化的,并且每个类都可以由各种不同的应用程序以多种不同的方式使用。每个类都可以用作由它定义的 main() 方法调用的独立类,也可以从另一个类或三个或四个主要应用程序之一调用。日志记录方法需要允许这种模块化。

import logging

class person:
    def __init__(self,name):
        self.name = name
        logger = logging.getLogger('person logger')
        logger.setLevel(logging.DEBUG)
        ch = logging.StreamHandler()
        formatter = logging.Formatter('%(name)s - %(message)s')
        ch.setFormatter(formatter)
        logger.addHandler(ch)

        logger.info(f'{self.name} exists')


if __name__ == '__main__':

    for name in ["Alice", "Bob", "Carlos"] :
        a = person(name)

预期结果:

person logger - Alice exists
person logger - Bob exists
person logger - Carlos exists

实际结果:

person logger - Alice exists
person logger - Bob exists
person logger - Bob exists
person logger - Carlos exists
person logger - Carlos exists
person logger - Carlos exists

【问题讨论】:

    标签: python python-3.x logging


    【解决方案1】:

    使用if logger.handlers 检查是否已经存在处理程序。或者,您每次创建 person 对象时都在添加处理程序。

    基本上:

    import logging
    
    class person:
        def __init__(self,name):
            self.name = name
            logger = logging.getLogger('person logger')
            logger.setLevel(logging.DEBUG)
            if not logger.handlers:
                ch = logging.StreamHandler()
                formatter = logging.Formatter('%(name)s - %(message)s')
                ch.setFormatter(formatter)
                logger.addHandler(ch)
    
            logger.info(f'{self.name} exists')
    
    
    if __name__ == '__main__':
    
        for name in ["Alice", "Bob", "Carlos"] :
            a = person(name)
    

    此外,大多数情况下,我们不是为类创建记录器,而是为模块创建记录器。

    对于大型项目,创建一个log_helper 模块,其中可能包含初始化函数:

    def getLogger(name):
        logger = logging.getLogger(name)
        # do some initialization...
        # like adding handlers
        return logger
    

    并在每个模块的顶部获取记录器:

    # person.py  Module person
    
    import log_helper
    
    logger = log_helper.getLogger("person") # or whatever you want
    
    # just use this logger...
    

    【讨论】:

    • 很有魅力,谢谢。我以为是多个记录器导致了问题,实际上是添加了多个处理程序。
    猜你喜欢
    • 2012-09-24
    • 2012-02-08
    • 1970-01-01
    • 1970-01-01
    • 2012-11-22
    • 2013-08-26
    • 1970-01-01
    • 2016-02-01
    • 1970-01-01
    相关资源
    最近更新 更多