python logging模块

import  logging模块

注意:root默认的等级是warning。即如果使用root打印日志,必须将等级设置成大于或者等级此等级才能成功打印日志,否则日志不会被传递到logger中。(切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!切记!!!)

logging是一个包,其实当你使用

import logging

这个语句的时候加载的就是_init.py里面的代码,加载成功,系统会自动创建root的logger。也就是系统在加载的时候已经创建了root的logger。并且会在加载的时候创建logger管理器。用户管理logger相关的操作信息。

 


logging.warning解析

当你使用
logging.warning("this is a message")
的时候系统使用的root的logger,并非你自己自定义的logger信息。

logging模块的源码如下:
def warning(msg, *args, **kwargs):
    """
    Log a message with severity 'WARNING' on the root logger. If the logger has
    no handlers, call basicConfig() to add a console handler with a pre-defined
    format.
    """
    if len(root.handlers) == 0:
        basicConfig()
    root.warning(msg, *args, **kwargs)
源码解析:
当调用logging模块的warning的时候,会判断当前的root的logger是否存在handlers,如果不存在就会调用
basicConfig给root设置一个handler和formatter,然后在执行root.warning函数,打印日志信息。
如果您已经设置了root的 handlers,则直接执行root.warning打印日志信息。

logger.warning解析

核心源码:
    def callHandlers(self, record):
        """
        Pass a record to all relevant handlers.

        Loop through all handlers for this logger and its parents in the
        logger hierarchy. If no handler was found, output a one-off error
        message to sys.stderr. Stop searching up the hierarchy whenever a
        logger with the "propagate" attribute set to zero is found - that
        will be the last logger whose handlers are called.
        """
        c = self
        found = 0
        while c:
            for hdlr in c.handlers:
                found = found + 1
                if record.levelno >= hdlr.level:
                    hdlr.handle(record)
            if not c.propagate:
                c = None    #break out
            else:
                c = c.parent
        if (found == 0):
            if lastResort:
                if record.levelno >= lastResort.level:
                    lastResort.handle(record)
            elif raiseExceptions and not self.manager.emittedNoHandlerWarning:
                sys.stderr.write("No handlers could be found for logger"
                                 " \"%s\"\n" % self.name)
                self.manager.emittedNoHandlerWarning = True
源码解析:
此处会自动判断当前到logger是否存在handlers,如果存在继续判断父级别是否存在,如果都存在并且self.propagate的值为1或者true,则父级别也会打印此日志。否则只有当前级别打印日志,
当然你也可以手动设置
logger.propagate=0或者False。这样日志就只会在当前的logger中打印,并不会自动传递到父级别

下面是测试代码

# -*- coding: utf-8 -*-
"""
@Time : 2020/1/6 12:04 下午
@Auth : charles.chai
@File :testlogger.py.py
@IDE :PyCharm
@Motto:ABC(Always Be Coding)
"""
import logging


class demo:
	def __init__(self):
		pass

	def getlogger11(self, name):
		logger = logging.getLogger(name)
		logger.setLevel(level=logging.INFO)
		handlers = logging.StreamHandler()
		fmt = logging.Formatter(fmt="%(asctime)s %(name)s [%(levelname)s] %(message)s")
		handlers.setFormatter(fmt=fmt)
		logger.addHandler(handlers)
		return logger
	def no_handler(self,name):
		logger=logging.getLogger(name)
		handlers=logging.StreamHandler()
		logger.addHandler(handlers)
		return logger


if __name__ == '__main__':
	t=demo()
	logger1=t.getlogger11("test1")
	logger2=t.no_handler("test1.test2")
	logger2.propagate=1
	logger2.warning("logger2.warning")
	logging.warning("tee")



下面是运行结果:

logger2.warning
2020-01-12 15:13:06,311 test1.test2 [WARNING] logger2.warning

Process finished with exit code 0

查看是否能打印日志的判断源码如下:

def isEnabledFor(self, level):
        """
        Is this logger enabled for level 'level'?
        """
        if self.disabled:
            return False

        try:
            return self._cache[level]
        except KeyError:
            _acquireLock()
            if self.manager.disable >= level:
                is_enabled = self._cache[level] = False
            else:
                is_enabled = self._cache[level] = level >= self.getEffectiveLevel()
            _releaseLock()

            return is_enabled

//getEffectiveLevel返回当前的loggerlevel的等级,如果当前logger未设置等级,则使用父级别的等级,作为返回值,如果父级别也没有设置,则直接往上找,直到找到root的级别。并且返回。
def getEffectiveLevel(self):
        """
        Get the effective level for this logger.

        Loop through this logger and its parents in the logger hierarchy,
        looking for a non-zero logging level. Return the first one found.
        """
        logger = self
        while logger:
            if logger.level:
                return logger.level
            logger = logger.parent
        return NOTSET

源码解析:
调用打印日志时都会自动传入一个等级,将传入的此等级跟当前logger设置的等级进行判断,是否>=当前的等级,如果是,则打印,否则不打印。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值