Python日志记录 - 记录器错误地导入到另一个文件

时间:2017-10-24 11:28:24

标签: python python-2.7 logging

我有两个python脚本(test1.py,test2.py),用于初始化自己的记录器。 test2.py从test1.py导入一个变量。奇怪的是,来自test1.py的记录器也会自动导入test2.py。

test1.py

import logging
import logging.handlers

LOG_FILENAME = '1.log'
rootLogger = logging.getLogger("default")
rootLogger.setLevel(logging.DEBUG)

# Set up a specific logger with our desired output level
consoleHandler = logging.StreamHandler()
rootLogger.addHandler(consoleHandler)

# Add the log message handler to the logger
handler = logging.FileHandler( LOG_FILENAME)
rootLogger.addHandler(handler)

a = 1
b = 2

test2.py

import logging
import logging.handlers

LOG_FILENAME = '2.log'
rootLogger = logging.getLogger("default")
rootLogger.setLevel(logging.DEBUG)

# Set up a specific logger with our desired output level
consoleHandler = logging.StreamHandler()
rootLogger.addHandler(consoleHandler)

# Add the log message handler to the logger
handler = logging.FileHandler( LOG_FILENAME)
rootLogger.addHandler(handler)


a = 3
from test1 import b
rootLogger.debug("a:%s",a)
rootLogger.debug("b:%s",b)

现在当我运行test2.py时,我希望只能调用test2.py中的rootLogger。更重要的是,我预计只会写入2.log。但奇怪的是,除了控制台上的重复输出外,还会生成1.log

$ python test2.py 
a:3
a:3
b:2
b:2

$ cat 1.log 
a:3
b:2

为什么会发生这种情况,以及避免此类情况的最佳做法是什么。

更新

我更改了getLogger调用以区分不同的记录器。

rootLogger = logging.getLogger(__name__)

但即使这样,“1.log”文件也会被创建,但这次它仍然是空的。

我理解我理想情况下不应该将rootLogger声明为全局,但是我必须将rootLogger处理程序传递给所有函数调用。

1 个答案:

答案 0 :(得分:0)

稍后的一些评论(感谢@schwobaseggl),我意识到了明显的问题。我遇到的问题是两个概念的组合:

  1. 从模块导入任何内容时,即使它是单个变量,也会执行所有模块级代码。

  2. 对具有相同名称的getLogger()的多次调用将始终返回对同一Logger对象的引用。 https://docs.python.org/2/library/logging.html

  3. 所以基本上,因为我在两个脚本中都使用了相同的记录器名称,并且两者中的global module code按顺序运行,我偶然在同一个记录器上添加了两次不同的FileHandler。

    <强>解决方案

    始终将记录器初始化代码放在if __name__ == '__main__':块中。

    import logging
    import logging.handlers
    
    a = 1
    b = 2
    
    if __name__ == '__main__':
        LOG_FILENAME = '1.log'
        rootLogger = logging.getLogger(__name__)
        rootLogger.setLevel(logging.DEBUG)
    
    # Set up a specific logger with our desired output level
        consoleHandler = logging.StreamHandler()
        rootLogger.addHandler(consoleHandler)
    
    # Add the log message handler to the logger
        handler = logging.FileHandler( LOG_FILENAME)
        rootLogger.addHandler(handler)