我正在设置python日志记录,如下所示:
def setup_logging(): loggers = (logging.getLogger("amcat"), logging.getLogger("scrapers"),logging.getLogger(__name__)) filename = "somefile.txt" sys.stderr = open(filename, 'a') handlers = (logging.StreamHandler(sys.stdout),logging.FileHandler(filename)) formatter = AmcatFormatter(date = True) for handler in handlers: handler.setLevel(logging.INFO) handler.setFormatter(formatter) for logger in loggers: logger.propagate = False logger.setLevel(logging.INFO) for handler in handlers: logger.addHandler(handler) logging.getLogger().handlers = []
启用了2个主要的模块记录器,它们都应该作为文件记录到控制台。错误被重定向到文件(理想情况下,错误也会在控制台中显示,但我尚未实现)
之后,我检查是否正确:
should_work = [ "amcat.scraping.scraper", "amcat.scraping.htmltools", "amcat.scraping.controller", "__main__"] loggerdict = logging.Logger.manager.loggerDict #all loggers for name, logger in loggerdict.items(): if name in should_work: print("\nlogger: "+name) #iterate through parents see if effective handlers are set correctly print(effectivehandlers(logger)) #test logger logger.info("test for {name}".format(**locals())) def effectivehandlers(logger): handlers = logger.handlers while True: logger = logger.parent handlers.extend(logger.handlers) if not (logger.parent and logger.propagate): break return handlers
控制台输出:
logger: __main__ [<logging.StreamHandler object at 0x3425d50>, <logging.FileHandler object at 0x3425dd0>] [2013-10-24 10:27:30 daily.py:133 INFO] test for __main__ logger: amcat.scraping.controller [<logging.StreamHandler object at 0x3425d50>, <logging.FileHandler object at 0x3425dd0>] [2013-10-24 10:27:30 daily.py:133 INFO] test for amcat.scraping.controller [2013-10-24 10:27:30 daily.py:133 INFO] test for amcat.scraping.controller logger: amcat.scraping.htmltools [<logging.StreamHandler object at 0x3425d50>, <logging.FileHandler object at 0x3425dd0>] [2013-10-24 10:27:30 daily.py:133 INFO] test for amcat.scraping.htmltools [2013-10-24 10:27:30 daily.py:133 INFO] test for amcat.scraping.htmltools logger: amcat.scraping.scraper [<logging.StreamHandler object at 0x3425d50>, <logging.FileHandler object at 0x3425dd0>] [2013-10-24 10:27:30 daily.py:133 INFO] test for amcat.scraping.scraper [2013-10-24 10:27:30 daily.py:133 INFO] test for amcat.scraping.scraper
这是文件输出:
[2013-10-24 10:27:30 daily.py:133 INFO] test for __main__ [2013-10-24 10:27:30 daily.py:133 INFO] test for amcat.scraping.controller [2013-10-24 10:27:30 daily.py:133 INFO] test for amcat.scraping.controller [2013-10-24 10:27:30 daily.py:133 INFO] test for amcat.scraping.htmltools [2013-10-24 10:27:30 daily.py:133 INFO] test for amcat.scraping.htmltools [2013-10-24 10:27:30 daily.py:133 INFO] test for amcat.scraping.scraper [2013-10-24 10:27:30 daily.py:133 INFO] test for amcat.scraping.scraper
如您所见,尽管禁用了传播并确保没有重复的处理程序,但输出还是两倍。这哪里出错了?
我想通了,谢谢Paco为我指出了正确的方向
事实证明,在getLogger被调用时,将向其添加处理程序:
getLogger
>>> print(effectivehandlers(logger)) [<logging.StreamHandler object at 0x305ad90>, <logging.FileHandler object at 0x305ae10>] >>> logging.getLogger(name) #the same logger <logging.Logger object at 0x7fa08fb9b2d0> >>> print(effectivehandlers(logger)) [<logging.StreamHandler object at 0x305ad90>, <logging.FileHandler object at 0x305ae10>, <logging.StreamHandler object at 0x305ad90>, <logging.FileHandler object at 0x305ae10>]
现在,孩子和父母都有相同的处理程序。因此重复输出。