Python日志重复

时间:2017-10-18 09:43:06

标签: python logging

我有四个文件,

  • Main.py
  • A.py
  • B.py
  • Log_System

我使用main来使用A.py和B.py的功能,所以现在我必须在我打电话时记录所有信息。

所以我写了一个名为log_system的脚本来为每个脚本文件创建日志处理程序,例如A.py,B.py

import logging

def fetchLogger(name="None") :
    logger = logging.getLogger(__name__)
    logger.setLevel(logging.DEBUG)

    if (name == "None"):
        #create File for Log
        handler = logging.FileHandler('./engine_log/Generic.log')
        handler.setLevel(logging.DEBUG)
        #log format 
        formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        handler.setFormatter(formatter)

        #adding the handler to Logging System
        logger.addHandler(handler)
    else: 
        #create File for Log
        handler = logging.FileHandler('./engine_log/'+str(name))
        handler.setLevel(logging.DEBUG)
        #log format 
        formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        handler.setFormatter(formatter)
        #adding the handler to Logging System
        logger.addHandler(handler)
    return logger

所以,如果我想在脚本文件A.py中使用日志记录,我会写这些行:

import log_system 
"""Log System Building """
file_name =  'A.py'
logger = log_system.fetchLogger(file_name)

def hello():
    try:
        logger.info("excuting Hello")
    except: 
        logger.debug("something went wrong in hello")

但我的日志文件

2017-10-18 14:59:28,695 - log_system - INFO - A.py-excuting Hello
2017-10-18 14:59:28,695 - log_system - INFO - A.py-excuting Hello
2017-10-18 14:59:28,695 - log_system - INFO - A.py-excuting Hello
2017-10-18 14:59:28,695 - log_system - INFO - A.py-excuting Hello
2017-10-18 14:59:28,695 - log_system - INFO - A.py-excuting Hello

它多次重复日志.... 那我该怎么办?

解决方案

logger = logging.getLogger(name)

if logger.hasHandlers(): 
    logger.handlers = []

logger.setLevel(logging.DEBUG)

#create File for Log
handler = logging.FileHandler('./engine_log/'+str(name))
handler.setLevel(logging.DEBUG)
#log format 
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
#adding the handler to Logging System
logger.addHandler(handler)

return logger

这就是我改变我的log_system代码的方法,所以如果我已经创建了一个日志处理程序,那么我只是清空了Handler列表,这样它就不会创建重复的记录。

2 个答案:

答案 0 :(得分:1)

每次调用fetch_logger时,都会向记录器添加新的FileHandler。每个FileHandler都会写入日志文件,从而导致文件中的重复输出。

一种解决方案是调用记录器的hasHandlers方法。如果在记录器上配置了任何处理程序,则返回True,然后您可以删除它们。

def fetchLogger(name="None") :
    logger = logging.getLogger(__name__)
    if logger.hasHandlers():
        # Logger is already configured, remove all handlers
        logger.handlers = []
    # Configure the logger as before.
    ...

答案 1 :(得分:0)

使用__name__变量作为记录器名称时,可能还有另一个原因。 记录器假定名称中的点表示亲子关系。如果您已经从树中更高的模块创建了一个记录器,则也将调用该记录器来处理该记录。

因此,如果您首先在模块'foo'中使用logger = logger.get_logger(__name__)并为其添加处理程序,
然后在模块'foo.bar'中another_logger = logger.get_logger(__name__)并向其中添加处理程序,
您已经创建了父级和子级。

在foo.bar模块中使用another_logger.info('Some text')将导致先执行'foo.bar'处理程序的处理程序,然后再执行'foo'处理程序的相同消息。