python logging - 消息未显示在子

时间:2016-07-15 01:19:41

标签: python logging

我在使用python的日志记录时遇到了一些困难。我有两个文件,main.py和mymodule.py。通常运行main.py,它将导入mymodule.py并从那里使用一些函数。但有时候,我会直接运行mymodule.py。

我尝试将其设置为仅在1个位置配置日志记录,但似乎有些错误。

这是代码。

# main.py
import logging
import mymodule

logger = logging.getLogger(__name__)

def setup_logging():
    # only cofnigure logger if script is main module
    # configuring logger in multiple places is bad
    # only top-level module should configure logger
    if not len(logger.handlers):
        logger.setLevel(logging.DEBUG)
        # create console handler with a higher log level
        ch = logging.StreamHandler()
        ch.setLevel(logging.DEBUG)
        formatter = logging.Formatter('%(levelname)s: %(asctime)s %(funcName)s(%(lineno)d) -- %(message)s', datefmt = '%Y-%m-%d %H:%M:%S')
        ch.setFormatter(formatter)
        logger.addHandler(ch)

if __name__ == '__main__':
    setup_logging()
    logger.info('calling mymodule.myfunc()')
    mymodule.myfunc()

和导入的模块:

# mymodule.py
import logging

logger = logging.getLogger(__name__)

def myfunc():
    msg = 'myfunc is being called'
    logger.info(msg)
    print('done with myfunc')


if __name__ == '__main__':
     # only cofnigure logger if script is main module
    # configuring logger in multiple places is bad
    # only top-level module should configure logger
    if not len(logger.handlers):
        logger.setLevel(logging.DEBUG)
        # create console handler with a higher log level
        ch = logging.StreamHandler()
        ch.setLevel(logging.DEBUG)
        formatter = logging.Formatter('%(levelname)s: %(asctime)s %(funcName)s(%(lineno)d) -- %(message)s', datefmt = '%Y-%m-%d %H:%M:%S')
        ch.setFormatter(formatter)
        logger.addHandler(ch)
    logger.info('myfunc was executed directly')
    myfunc()

当我运行代码时,我看到了这个输出:

$>python main.py
INFO: 2016-07-14 18:13:04 <module>(22) -- calling mymodule.myfunc()
done with myfunc

但我希望看到这个:

$>python main.py
INFO: 2016-07-14 18:13:04 <module>(22) -- calling mymodule.myfunc()
INFO: 2016-07-14 18:15:09 myfunc(8) -- myfunc is being called
done with myfunc

任何人都知道为什么第二次logging.info调用没有打印到屏幕?提前谢谢!

3 个答案:

答案 0 :(得分:2)

切普纳是对的。我全神贯注于这个问题。问题仅在于您的主脚本

16 log = logging.getLogger() # use this form to initialize the root logger
17 #log = logging.getLogger(__name__) # never use this one

如果使用第17行,那么导入的python模块将不会记录任何消息

在你的submodule.py

import logging
logger = logging.getLogger()
logger.debug("You will not see this message if you use line 17 in main")

希望这篇帖子可以帮助那些陷入这个问题的人。

答案 1 :(得分:1)

记录器存在于层次结构中,顶部有一个根记录器(用logging.getLogger()检索,没有参数)。每个记录器都从其父级继承配置,记录器本身的任何配置都会覆盖继承的配置。在这种情况下,您永远不会在main.py中配置根记录器,只配置特定于模块的记录器。因此,永远不会配置mymodule.py中特定于模块的记录器。

最简单的解决方法可能是在logging.basicConfig中使用main.py来设置您希望所有记录器共享的选项。

答案 2 :(得分:0)

虽然 logging -package在概念上使用点作为分隔符排列在命名空间层次结构中,但所有记录器隐式继承自root记录器(如每个类)在Python 3中默默地继承自object)。每个记录器都将日志消息传递给其父级。

在您的情况下,您的记录器链接不正确。尝试在两个模块中添加print(logger.name),您将意识到, main.py 中的记录器实例化等同于

logger = logging.getLogger('__main__')

mymodule.py 中,您有效地制作

logger = logging.getLogger('mymodule')

来自myfunc()的记录INFO消息的调用直接传递root记录器(因为 main.py 中的记录器 >其祖先),其中设置了处理程序(在这种情况下,默认消息调度将被触发,请参阅here