使用Python日志模块时日志重复输出

189 投票
19 回答
130825 浏览
提问于 2025-04-17 00:15

我正在使用Python的日志记录功能。以下是我的代码:

import os
import time
import datetime
import logging
class Logger :
   def myLogger(self):
      logger = logging.getLogger('ProvisioningPython')
      logger.setLevel(logging.DEBUG)
      now = datetime.datetime.now()
      handler=logging.FileHandler('/root/credentials/Logs/ProvisioningPython'+ now.strftime("%Y-%m-%d") +'.log')
      formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
      handler.setFormatter(formatter)
      logger.addHandler(handler)
      return logger

我遇到的问题是,每次调用logger.info的时候,日志文件里会出现多条记录。我该怎么解决这个问题呢?

19 个回答

101

我已经把 logger 用作了一个单例,并检查了 if not len(logger.handlers),但是还是出现了重复的记录:先是格式化的输出,然后是未格式化的。

在我的情况下的解决办法是:logger.propagate = False

感谢 这个回答文档

130

从Python 3.2开始,你可以先检查一下是否已经有处理程序(handlers)存在。如果有的话,可以先把它们清除掉,然后再添加新的处理程序。这在调试的时候特别方便,尤其是当你的代码里包含了日志记录的初始化时。

if (logger.hasHandlers()):
    logger.handlers.clear()

logger.addHandler(handler)
146

函数 logging.getLogger() 会根据你给定的名字返回同一个实例。

问题在于,每次你调用 myLogger() 时,它都会往这个实例里添加一个新的处理器,这样就会导致日志重复记录。

也许可以这样做?

import os
import time
import datetime
import logging

loggers = {}

def myLogger(name):
    global loggers
    
    if loggers.get(name):
        return loggers.get(name)
    else:
        logger = logging.getLogger(name)
        logger.setLevel(logging.DEBUG)
        now = datetime.datetime.now()
        handler = logging.FileHandler(
            '/root/credentials/Logs/ProvisioningPython' 
            + now.strftime("%Y-%m-%d") 
            + '.log')
        formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
        handler.setFormatter(formatter)
        logger.addHandler(handler)
        loggers[name] = logger
                       
        return logger

撰写回答