Python日志记录器(logging)多次记录相同的条目。

15

我有一个这样的日志记录器初始化函数:

def generate_logger():
    import logging
    LOG_FILENAME = os.path.join(PROJECT_DIR, "mylog.log")
    FORMAT = "%(asctime)s : %(message)s"
    logger = logging.getLogger()
    logger.setLevel(logging.INFO)
    fh = logging.FileHandler(LOG_FILENAME)
    formatter = logging.Formatter(FORMAT)
    fh.setFormatter(formatter)
    logger.addHandler(fh)
    return logger

而在我的代码的某个部分,我有这样的异常捕捉:

logger = generate_logger()
except AttributeError:
    logger.error('Opps we got an error')

奇怪的是我得到了相同的错误两次,但只能捕获一次,当我用print "test"替换logger.error('Opps we got an error')时,我只打印了一次"test"。

问题和解决方案是什么?

5个回答

15

每次调用该函数时,您都在将新的 FileHandler 添加到根记录器中:没有名称参数的 logger.getLogger() 调用每次返回相同的记录器对象。

您应该仅调用一次 generate_logger(),然后通过调用 logger.getLogger() 来获取相同的记录器对象:

generate_logger()

# .... some time later

log = logger.getLogger()
except AttributeError:
   log.error('Opps we got an error')

(请注意,现在您不需要让generate_logger()返回任何值)


13

我也遇到了同样的问题,并找到了这个页面。是的,我也创建了多个处理程序。在generate_logger()中,您可以检查是否有其他处理程序并将它们删除。

def generate_logger():
    import logging
    LOG_FILENAME = os.path.join(PROJECT_DIR, "mylog.log")
    FORMAT = "%(asctime)s : %(message)s"
    logger = logging.getLogger()
    logger.setLevel(logging.INFO)
    # Reset the logger.handlers if it already exists.
    if logger.handlers:
        logger.handlers = []
    fh = logging.FileHandler(LOG_FILENAME)
    formatter = logging.Formatter(FORMAT)
    fh.setFormatter(formatter)
    logger.addHandler(fh)
    return logger

3

我认为可能是日志记录器中添加了两个处理程序。也许在某些时候会自动添加一个处理程序。


2
你可能有两个处理程序指向同一个结果日志。
你创建了多少个处理程序?你执行了多少次generate_logger?每次执行generate_logger都会创建另一个指向相同文件的处理程序,导致潜在的重复。

0

你可以使用单例设计模式来实现:

43 类 Singleton(type):
44 """
45 定义一个实例操作,让客户端可以访问其唯一的实例。
46 """
47
49 def init(cls, name, bases, attrs, **kwargs):
50 super().init(name, bases, attrs)
51 cls._instance = None
52
53 def call(cls, *args, **kwargs):
54 if cls._instance is None:
55 cls._instance = super().call(*args, **kwargs)
56 return cls._instance
57
58
59
60 def _setup_logger(name, log_file, level=logging.INFO):
61 """函数设置尽可能多的记录器"""
62
63 handler = logging.FileHandler(log_file)
64 handler.setFormatter(formatter)
65 logger = logging.getLogger(name)
66 logger.setLevel(level)
67 logger.addHandler(handler)
68
69 return logger
70
71 类 Logger(metaclass=Singleton):
72
73 def init(self, file_name, level):
74 if not (isinstance(file_name, str) and
75 isinstance(level, int)):
76 raise ValueError("无效参数")
77
78 self.log_inf = _setup_logger('inf', file_name+'.inf', level)
79 self.log_err = _setup_logger('err', file_name+'.err', level)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接