首页 > 编程 > Python > 正文

详解Python logging调用Logger.info方法的处理过程

2020-02-23 06:26:37
字体:
来源:转载
供稿:网友

本次分析一下Logger.info的流程

1. Logger.info源码:

 def info(self, msg, *args, **kwargs):  """  Log 'msg % args' with severity 'INFO'.  To pass exception information, use the keyword argument exc_info with  a true value, e.g.  logger.info("Houston, we have a %s", "interesting problem", exc_info=1)  """  if self.isEnabledFor(INFO):   self._log(INFO, msg, args, **kwargs)

注释中反应了可以通过 msg和不定参数args来进行日志的格式化。
真实的调用为:_log方法:

2. Logger._log方法:

 def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False):  """  Low-level logging routine which creates a LogRecord and then calls  all the handlers of this logger to handle the record.  """  sinfo = None  if _srcfile:   #IronPython doesn't track Python frames, so findCaller raises an   #exception on some versions of IronPython. We trap it here so that   #IronPython can use logging.   try:    fn, lno, func, sinfo = self.findCaller(stack_info)   except ValueError: # pragma: no cover    fn, lno, func = "(unknown file)", 0, "(unknown function)"  else: # pragma: no cover   fn, lno, func = "(unknown file)", 0, "(unknown function)"  if exc_info:   if isinstance(exc_info, BaseException):    exc_info = (type(exc_info), exc_info, exc_info.__traceback__)   elif not isinstance(exc_info, tuple):    exc_info = sys.exc_info()  record = self.makeRecord(self.name, level, fn, lno, msg, args,         exc_info, func, extra, sinfo)  self.handle(record)

最后两行:

生成日志记录:

record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra, sinfo)

处理日志记录

self.handle(record)

2 生成日志记录:

 def makeRecord(self, name, level, fn, lno, msg, args, exc_info,     func=None, extra=None, sinfo=None):  """  A factory method which can be overridden in subclasses to create  specialized LogRecords.  """  rv = _logRecordFactory(name, level, fn, lno, msg, args, exc_info, func,        sinfo)  if extra is not None:   for key in extra:    if (key in ["message", "asctime"]) or (key in rv.__dict__):     raise KeyError("Attempt to overwrite %r in LogRecord" % key)    rv.__dict__[key] = extra[key]  return rv

调用_logRecordFactory初始化一个日志记录实例,_logRecordFactory 其实就是LogRecord类,初始化时,可能包含logger的name, level、调用的函数、行号、日志字符串、模板参数、堆栈信息等。

再看extra信息,extra到底有何用?现在从代码中可以看到,只是更新到生成的日志记录实例的__dict__中去.猜测:肯定会在生成最终的日志字符串的时候会用到。继续往下看。

3 处理日志记录self.handle(record):

Logger继承自Filterer,

 def handle(self, record):  """  Call the handlers for the specified record.  This method is used for unpickled records received from a socket, as  well as those created locally. Logger-level filtering is applied.  """  if (not self.disabled) and self.filter(record):   self.callHandlers(record)            
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表