每个函数或模块的Python记录器

每个函数或模块的Python记录器,python,logging,Python,Logging,我正在尝试使用python登录,并且已经阅读了一些博客。一个让我感到困惑的问题是,是为每个函数还是为每个模块创建记录器。在这种情况下,建议为每个函数设置一个记录器。例如: import logging def foo(): logger = logging.getLogger(__name__) logger.info('Hi, foo') class Bar(object): def __init__(self, logger=None): sel

我正在尝试使用python登录,并且已经阅读了一些博客。一个让我感到困惑的问题是,是为每个函数还是为每个模块创建记录器。在这种情况下,建议为每个函数设置一个记录器。例如:

import logging

def foo():
    logger = logging.getLogger(__name__)
    logger.info('Hi, foo') 

class Bar(object):
    def __init__(self, logger=None):
        self.logger = logger or logging.getLogger(__name__)

    def bar(self):
        self.logger.info('Hi, bar')
给出的理由是

默认情况下,logging.fileConfig和logging.dictConfig禁用现有记录器。所以,文件中的这些设置将不会应用于记录器。最好在你需要的时候得到记录器。创建或获取记录器很便宜

我在其他地方阅读的推荐方式如下所示。博客上说,这种方法看起来无害,但实际上存在一个陷阱


我发现前一种方法很乏味,因为我必须记住在每个函数中使用记录器。此外,在每个功能中使用记录器肯定比在每个模块中使用一次要昂贵。这篇博客的作者提倡的不是问题吗?以下日志记录最佳实践是否可以避免此问题?

我同意您的看法;至少可以说,在您使用的每一个函数中加入记录器会产生太多不必要的认知开销

博客作者说得对,在使用记录器之前,您应该小心地正确初始化(配置)记录器

但他建议的方法只有在您无法控制应用程序加载和应用程序入口点的情况下才有意义(通常您是这样做的)

为了避免过早(隐式)创建日志记录器(如
logging.info()
logging.error()
,等等),如果事先没有配置根日志记录器,只需确保在记录日志之前配置日志记录器即可

中还建议在启动其他线程之前从主线程初始化记录器

Python的日志教程(和)可以作为参考,但要获得更简明的概述,请参阅

从多个模块记录日志的简单蓝图 看一下这个修改过的:

在标准输出上生成此文件(请注意正确的
名称
):


谢谢你的解释。如果没有为根记录器定义处理程序,则指向
basicConfig
文档的链接将引导我阅读
函数debug()、info()、warning()、error()和critical()将自动调用basicConfig()。
如果根记录器已经为其配置了处理程序,则此函数不会执行任何操作。我也很感激强调在登录之前确保配置日志记录器。如果在basicConfig函数之前添加了
logging.info('hello')
,那么日志将不会打印任何内容。这个答案让我相信,在每个函数中获取logger对象表明了对日志模块工作方式的误解。如果您遵循“确保在登录之前配置日志记录程序”的最佳实践,则每个模块的日志记录程序应该没有问题。不客气,我很高兴我们解决了这个问题
:-)
不受欢迎的答案。
logging.fileConfig和logging.dictConfig默认情况下禁用现有记录器
;这是否意味着,如果您使用这些函数初始化记录器,其他记录器初始化未通过dict/文件配置的其他记录器将无法工作?
import logging
logger = logging.getLogger(__name__)

def foo():
    logger.info('Hi, foo') 

class Bar(object):
    def bar(self):
        logger.info('Hi, bar')
# myapp.py
import logging
import mylib

# get the fully-qualified logger (here: `root.__main__`)
logger = logging.getLogger(__name__)    

def main():
    logging.basicConfig(format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
                        level=logging.DEBUG)
    # note the `logger` from above is now properly configured
    logger.debug("started")
    mylib.something()

if __name__ == "__main__":
    main()
# mylib.py
import logging

# get the fully-qualified logger (here: `root.mylib`)
logger = logging.getLogger(__name__)

def something():
    logger.info("something")
$ python myapp.py
2017-07-12 21:15:53,334 __main__     DEBUG    started
2017-07-12 21:15:53,334 mylib        INFO     something