原文地址:
http://wenku.baidu.com/view/00364057312b3169a451a4ec.html
Nova-Logging 思路分析
1. nova-root 建立(替换默认的logging.root)
1.1 nova-root建立的总体思路
新建NovaLogger类继承logging.Logger,,新建NovaRootLogger继承NovaLogger类。将NovaRootLogger的实例赋值给logging.root。由于NovaLogger继承了logging.Logger的“root”和“manager”属性,将logging.root同时赋给了NovaLogger.root和NovaLogger.manager.root。
1.2 nova-root建立代码分析
1. nova-api(或其他服务)服务启动的时候会调用logging.setup(),该函数会调用nova.log. setup()函数。
2. if not isinstance(logging.root, NovaRootLogger)
logging._acquireLock():
该语句判断当前logging.root是否属于类NovaRootLogger,否则执行执行该语句块中加锁并执行下面语句。默认的logging.root不属于NovaRootLogger,而属于Logging。
内置函数isinstance(object,classinfo):
Return true if the object argument is an instance of the classinfo argument, or of a (direct or indirect) subclass thereof. Also return true if classinfo is a type object and object is an object of that type. If object is not a class instance or an object of the given type, the function always returns false. If classinfo is neither a class object nor a type object, it may be a tuple of class or type objects, or may recursively contain other such tuples (other sequence types are not accepted). If classinfo is not a class, type, or tuple of classes, types, and such tuples, a TypeError exception is raised. Changed in version 2.2: Support for a tuple of type information was added.
3. for handler in logging.root.handlers:
logging.root.removeHandler(handler)
循环从logging.root 移除添加进去的handler。
3. logging.root = NovaRootLogger("nova")
该语句构造一个NovaRootLogger类实例。调用自身的__init__()函数。该函数设置自身属性streamlog 为 StreamHandler(),同时调用父类的__init__()函数。
NovaRootLogger继承自NovaLogger,执行NovaLogger的__init__()函数。该函数调用父类(Logging.logger)的构造函数,并调用自身的setup_from_flags()从Flags中取出标记并设置self.setLevel(level)。 其中level = globals()[level_name]语句为从全局变量空间中获取level_name对应的值。即该文件开始处声明的变量值:
CRITICAL = logging.CRITICAL
FATAL = logging.FATAL
ERROR = logging.ERROR
WARNING = logging.WARNING
WARN = logging.WARN
INFO = logging.INFO
DEBUG = logging.DEBUG
NOTSET = logging.NOTSET
4. NovaLogger.root = logging.root
NovaLogger.manager.root = logging.root
将NovaRootLogger实例赋值给NovaLogger类的两个属性值。
NovaLogger.root和NovaLogger.manager均继承于logging.logger类。其代码位于logging包中国的__init__.py:
root = RootLogger(WARNING)
Logger.root = root
Logger.manager = Manager(Logger.root)
该处实现了类属性在类外(非类语句块中)赋值特点。
5. for logger in NovaLogger.manager.loggerDict.itervalues():
logger.root = logging.root
if isinstance(logger, logging.Logger):
NovaLogger.manager._fixupParents(logger)
NovaLogger.manager.loggerDict["nova"] = logging.root
循环处理NovaLogger.manager.loggerDict.itervalues()中的logger。设置NovaLogger.manager中的一些属性。完成NovaRootLogger的建立。根据logging的特点。以后其他的logger都继承该logger为父类。
2.nova-child 建立并应用(继承新建立的logging.root)
1.log=logging.getLogge('nova.api.ec2.admin')
创建一个logger实例nova.api.ec2.admin,该实例继承NovaRootLogger类的实例特性。
2.log.addHandler(logging.StreamHandler(self.stream))
调用NovaLogger的addHandler函数完成。