openstack 早期版本(非oslo.log)log输出过程浅析

本文深入剖析了openstack nova f版的日志模块,从启动配置到日志记录的全过程。通过入口函数,分析了如何创建ContextAdapter,设置log级别,配置handler,特别是对syslog、logfile和标准输出的处理。还探讨了如何将ERROR级别日志输出到文本,以及如何处理logrotate,确保日志记录的连续性。
摘要由CSDN通过智能技术生成

本文以nova f版为例,浅析openstack log模块的启动及配置过程。

在nova-api的启动模块中,可以看到类似如下代码:

from nova.openstack.common import log as logging
logging.setup("nova")

此为入口函数,我们看一下函数代码:

def setup(product_name):
    """Setup logging."""
    sys.excepthook = _create_logging_excepthook(product_name)

    if CONF.log_config:
        try:
            logging.config.fileConfig(CONF.log_config)
        except Exception:
            traceback.print_exc()
            raise
    else:
        _setup_logging_from_conf(product_name)

其中sys.excepthook = _create_logging_excepthook(product_name)创建了一个critical钩子callback函数,具体作用在用到时我们进行了解。
先继续往下看在默认情况下所调用的_setup_logging_from_conf(product_name):

def _setup_logging_from_conf(product_name):
    log_root = getLogger(product_name).logger
    for handler in log_root.handlers:
        log_root.removeHandler(handler)

    if CONF.use_syslog:
        facility = _find_facility_from_conf()
        syslog = logging.handlers.SysLogHandler(address='/dev/log',
                                                facility=facility)
        log_root.addHandler(syslog)

    logpath = _get_log_file_path()
    if logpath:
        filelog = logging.handlers.WatchedFileHandler(logpath)
        log_root.addHandler(filelog)

        mode = int(CONF.logfile_mode, 8)
        st = os.stat(logpath)
        if st.st_mode != (stat.S_IFREG | mode):
            os.chmod(logpath, mode)

    if CONF.use_stderr:
        streamlog = ColorHandler()
        log_root.addHandler(streamlog)

    elif not CONF.log_file:
        # pass sys.stdout as a positional argument
        # python2.6 calls the argument strm, in 2.7 it's stream
        streamlog = logging.StreamHandler(sys.stdout)
        log_root.addHandler(streamlog)

    if CONF.publish_errors:
        log_root.addHandler(PublishErrorsHandler(logging.ERROR))

    for handler in log_root.handlers:
        datefmt = CONF.log_date_format
        if CONF.log_format:
            handler.setFormatter(logging.Formatter(fmt=CONF.log_format,
                                                   datefmt=datefmt))
        handler.setFormatter(LegacyFormatter(datefmt=datefmt))

    if CONF.verbose or CONF.debug:
        log_root.setLevel(logging.DEBUG)
    else:
        log_root.setLevel(logging.INFO)

    level = logging.NOTSET
    for pair in CONF.default_log_levels:
        mod, _sep, level_name = pair.partition('=')
        level = logging.getLevelName(level_name)
        logger = logging.getLogger(mod)
        logger.setLevel(level)
        for handler in log_root.handlers:
            logger.addHandler(handler)

首先,log_root = getLogger(product_name).logger中的getLogger(product_name)生成了一个ContextAdapter类实例,这个类继承自python内建logging库的LoggerAdapter类,其logger属性生成了logging库中一个name=’nova’的Logger object。继续:

    for handler in log_root.handlers:
        log_root.removeHandler(handler)

此段代码逻辑重置了logger的handlers,具体作用之后讲解。继续:

    if CONF.use_syslog:
        facility = _find_facility_from_conf()
        syslog = logging.handlers.SysLogHandler(address='/dev/log',
                                                facility=facility)
        log_root.addHandler(syslog)

如果使用了syslog协议,增加将logger记录的log发送至指定syslog目的地址的handler。相当简单不再解析。继续:

    logpath = _get_log_file_path()
    if logpath:
        filelog = logging.handlers.WatchedFileHandler(logpath)
        log_root.addHandler(filelog)

        mode = int(CONF.logfile_mode, 8)
        st = os.stat(logpath)
        if st.st_mode !&#
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值