logging Python,python logging模块默认日志

  logging Python,python logging模块默认日志

  本文主要介绍用于代码分析的python标准库的日志模块。有需要的朋友可以借鉴一下,希望能有所帮助。祝大家进步很大,早日升职加薪。

  00-1010问题1:如何获取调用者的(文件名,行号,函数名)?FindCaller如下:currentframe函数的定义:问题logger对象的层次结构,父子关系是如何实现的?管理器的getLogger()定义如下:

  

目录

 

  当添加一个新的LogRecord时,Logger类的_log方法最终会被调用,这将首先创建一个logrecord对象。日志对象需要(文件名,行号,函数名)参数信息。这是通过以下语句获得的:

  fn,lno,func=self.findCaller()

  

问题1:如何获取caller的(文件名,行号,函数名)?

 

  F=currentframe() #f是一个frame对象,每个方法调用都会生成一个frame对象,放在程序栈中。

  如果f不是None:

  f=f.f_back

  rv=(未知文件),0,(未知函数)

  而hasattr(f, f_code):

  Co=f.f_code #获取code对象,包含filename属性和funcname属性。

  filename=OS . path . norm case(co . co _ filename)

  如果filename==_ src file 3360 # _ src file是这个模块文件的文件名,当文件名不再相同时。

  F=f.f_back #获取外部调用方的帧,就是这么取的。

  继续

  rv=(文件名,f.f_lineno,co.co_name)

  破裂

  返回rv

  

findCaller内容如下:

 

  def当前帧():

  返回调用方堆栈框架的框架对象。

  尝试:

  抛出一个异常,这将生成一个回溯对象,包括一个框架对象。

  例外:

  #sys.exc_traceback.tb_frame当前帧,f_back调用的帧

  return sys . exc _ trace back . TB _ frame . f _ back

  #sys。_getframe(3)不返回当前帧,应计算3,减少循环次数,它返回logger.error()的帧

  if hasattr(sys, _ getframe ): current frame=lambda : sys。_getframe(3)

  

currentframe函数的定义:

 

  首先,日志模块中的logger层次结构是树形结构,这个关系的根是‘root’。

  Root=rootLogger(警告)# root Logger类是logger的子类。它没有特殊功能,但它的名字被定义为“根”。

  Logger.root=root

  logger . Manager=Manager(logger . root)

  当调用logging.getLogger()来获取记录器时,如果参数为空,则返回“root”。否则,调用管理器的getLogger()方法来获取记录器。

  定义ge

  tLogger(name=None):

   """

   Return a logger with the specified name, creating it if necessary.

   If no name is specified, return the root logger.

   """

   if name:

   return Logger.manager.getLogger(name)

   else:

   return root

  

 

  

Manager的getLogger()定义如下:

 

  

 def getLogger(self, name):

 

  Manager对象中的loggerDict字典,存放logger名字和logger对象的映射关系。PlaceHolder类,是一个容器。

  例如,名字为'sell'的PlaceHolder对象,首先还不存在'sell'的logger,然后,所以以'sell‘开头的logger在这个对象内都存在一个引用,如'sell.food','sell.cloth.china'等已有的logger对象。 当调用getLogger()获取一个未存在的logger时,如名字为'level1.level2', 首先创建一个名字为'level1.level2'的logger对象,并存于loggerDict中。然后,调用_fixupParents()。

  _fixupParents()的作用:

  在这个名字的层级链上,找到第一个logger对象,将其作为父亲,并返回。链上不是logger对象的名字,创建一个PlaceHolder对象(如果未创建),将自己加入其中。

  例如,新增‘level1.level2.level3’的logger,调用_fixupParents将创建一个名字为'level1.level2‘的PlaceHolder对象,创建一个名字为’level1‘的PlaceHolder对象,并将’level1.level2.level3‘这个logger分别加入以上两个PlaceHolder对象容器内,将它的父亲设定为’root‘。

  总之,_fixupParents是使logger对象指向真正的父亲节点(logger对象),并将logger自己加入到所有上层的PlaceHolder对象容器内。

  如果获取一个名字已存在于loggerDict中,并且这个名字对应的是一个先前创建的PlaceHolder对象。首先,创建一个对应名字的logger对象。然后,调用_fixupChild(),修正这个PlaceHolder对象所包含的下游logger对象的父亲。最后,调用_fixupParent(),作用与上一步相同。

  父子层级关系,主要作用是,当logger对象的propagate属性值1(默认值)时,每条logRecord记录都会传给父logger处理。这样可以只需要定义好‘root’根logger对象,其他的logger定义个名字,根据模块名,类名等,然后绑定一个NullHandler。最后,所有的logRecord将交给’root‘统一处理处理。这是多模块产生统一格式log的方式。

  以上就是代码解析python标准库logging模块的详细内容,更多关于python标准库logging模块的资料请关注盛行IT软件开发工作室其它相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: