我正在尝试使用python中的日志记录并阅读了几个博客。导致混淆的一个问题是,是为每个功能还是按模块创建记录器。在此Blog: Good logging practice in 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默认禁用现有记录器。因此,文件中的设置将不会应用于您的记录器。最适合在需要时获取记录器。创建或获取记录器很便宜。
我在其他地方阅读的推荐方式如下所示。该博客指出了这种方法"looks harmless, but actually, there is a pitfall"
。
import logging
logger = logging.getLogger(__name__)
def foo():
logger.info('Hi, foo')
class Bar(object):
def bar(self):
logger.info('Hi, bar')
我发现前一种方法很乏味,因为我必须记住在每个函数中都有记录器。另外,在每个功能中获取记录器肯定比每个模块一次更昂贵。博客的作者是否主张非问题?以下日志记录最佳做法会避免此问题吗?
答案 0 :(得分:4)
我同意你的意见;至少可以说,在你使用的每个函数中获取记录器会产生太多不必要的认知开销。
该博客的作者是正确的,在使用它们之前,您应该小心地正确初始化(配置)您的记录器。
但他建议的方法只有在您无法控制应用程序加载和应用程序入口点(通常是这样做)的情况下才有意义。
为避免过早(隐式)创建记录器that happens with a first call to any of the message logging functions(如logging.info()
,logging.error()
等),如果未事先配置根记录器,只需确保在记录之前配置记录器。
在Python docs中,还建议在启动其他线程之前从主线程初始化记录器。
Python的日志教程(basic和advanced)可以作为参考,但为了更简洁的概述,请查看logging section of The Hitchhiker's Guide to Python。
查看此修改后的example from Python's logging tutorial:
# 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")
在stdout
上生成此内容(请注意正确的name
):
$ python myapp.py
2017-07-12 21:15:53,334 __main__ DEBUG started
2017-07-12 21:15:53,334 mylib INFO something