Ceilometer项目源码分析----ceilometer报警器状态评估方式之单一报警器状态评估的具体实现

前端之家收集整理的这篇文章主要介绍了Ceilometer项目源码分析----ceilometer报警器状态评估方式之单一报警器状态评估的具体实现前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

感谢朋友支持博客,欢迎共同探讨交流,由于能力和时间有限,错误之处在所难免,欢迎指正!

如果转载,请保留作者信息。
博客地址:http://blog.csdn.net/gaoxingnengjisuan
邮箱地址:dong.liu@siat.ac.cn

PS:最近没有登录博客,很多朋友的留言没有看见,这里道歉!还有就是本人较少上QQ,可以邮件交流。


ceilometer报警器状态评估方式之单一报警器状态评估的具体实现

这篇博客将会解析单一报警器状态评估的具体实现,即/ceilometer/alarm/evaluator/threshold.py中类ThresholdEvaluator所实现的内容。在这个类所实现的若干方法中,所有方法都被方法evaluate所调用,最终实现单一报警器状态的评估操作,我们来看看这个类所有重要方法的实现。


1 def _statistics(self,alarm,query)

def _statistics(self,query):
    """
    获取query和meter_name(meter_name=alarm.rule['meter_name'])指定的监控统计数据列表;   
    client_class是Client(ceilometerclient/v2/client.py),从Client的属性可以看出statistics是StatisticsManager(ceilometerclient/v2/statistics.py),它的list函数调用,传入的参数是alarm的meter_name(在alarm的属性中可以看到),查询条件query,以及alarm的period;
    最终的返回结果为根据query和period制定的查询条件查询meter_name指定的metrics的结果;
        
    通过客户端通过HTTP协议GET方法获取符合查询条件的statistics列表;
    最终的返回结果为meter_name指定的metrics的结果statistics列表;
    """
    LOG.debug(_('stats query %s') % query)
    try:
        return self._client.statistics.list(
            meter_name=alarm.rule['meter_name'],q=query,period=alarm.rule['period'])
    except Exception:
        LOG.exception(_('alarm stats retrieval Failed'))
        return []
方法小结:

通过客户端通过HTTP协议GET方法获取符合查询条件的statistics列表;
最终的返回结果为meter_name指定的metrics的结果statistics列表;


2 def _sufficient(self,statistics)

def _sufficient(self,statistics):
    """
    确保报警器评估具有足够的数据(仲裁人数);
    1.根据统计数据的数目来判断是否有足够的数据用于报警器的评估(最小值要大于1);
    2.如果sufficient为0说明用于仲裁的数目不够,则需要刷新报警器的状态为'insufficient data';
    """
        
    """
    根据统计数据的数目来判断是否有足够的数据用于报警器的评估(最小值要大于1);
    """
    sufficient = len(statistics) >= self.quorum
        
    """
    如果sufficient为0说明用于仲裁的数目不够,则需要刷新报警器的状态为'insufficient data';
    """
    if not sufficient and alarm.state != evaluator.UNKNOWN:
        reason = _('%d datapoints are unknown') % alarm.rule[
            'evaluation_periods']
        reason_data = self._reason_data('unknown',alarm.rule['evaluation_periods'],None)
        self._refresh(alarm,evaluator.UNKNOWN,reason,reason_data)
    return sufficient
方法小结:

确保报警器评估具有足够的数据(仲裁人数);
1.根据统计数据的数目来判断是否有足够的数据用于报警器的评估(最小值要大于1);
2.如果sufficient为0说明用于仲裁的数目不够,则需要刷新报警器的状态为'insufficient data';


3 def _transition(self,statistics,compared)

def _transition(self,compared):
    """
    根据statistics是否满足触发报警器条件,来更新报警器报警状态(alarm或ok);
    1.验证所有的statistics是否满足触发报警器的条件;
      * 所有的statistics均满足触发报警器条件;
      * 所有的statistics均不满足触发报警器条件;
      * 报警器的数据状态为'insufficient data'(数据不充足);
    2.如果所有的statistics均满足报警条件,则说明需触发报警,报警器的状态设置为'alarm';
    3.如果所有的statistics均不满足报警条天,则说明报警器处于正常状态,报警器的状态设置为'ok';
    4.如果当前报警器的状态为'insufficient data'(数据不充足),则根据最后一个statistics,来判断报警器的发展状态的趋势,进而确定报警器的报警状态;
      * 如果最后一个statistics符合触发报警器的条件,则说明报警器有转换为ALARM状态的趋势,则设置报警器的报警状态为alarm;
      * 如果最后一个statistics不符合触发报警器的条件,则说明报警器有转换为OK状态的趋势,则设置报警器的报警状态为ok;
    """
        
    """
    如果distilled为true,说明所有的statistics均满足触发报警器条件;
    """
    distilled = all(compared)
    

    """
    如果unequivocal为true,说明所有的statistics均满足或均不满足触发报警器条件;
    """
    unequivocal = distilled or not any(compared)
    """
    验证报警器的状态是否为'insufficient data'(数据不充足);
    """
    unknown = alarm.state == evaluator.UNKNOWN
    # repeat_actions:表示每个评估周期都要重新触发的actions;
    continuous = alarm.repeat_actions

    """
    如果所有的statistics均满足报警条件,则说明需触发报警,报警器的状态设置为'alarm';
    如果所有的statistics均不满足报警条天,则说明报警器处于正常状态,报警器的状态设置为'ok';
    """
    if unequivocal:
        """
        如果所有的statistics均满足报警条件,则说明需触发报警,报警器的状态设置为'alarm';
        如果所有的statistics均不满足报警条天,则说明报警器处于正常状态,报警器的状态设置为'ok';
        """
        state = evaluator.ALARM if distilled else evaluator.OK
        reason,reason_data = self._reason(alarm,distilled,state)
            
        """
        如果报警器的状态和要赋予的状态不同,或者continuous为true,则需要刷新报警器的状态为指定状态;
        """
        if alarm.state != state or continuous:
            self._refresh(alarm,state,reason_data)
        
    """
    如果当前报警器的状态为'insufficient data',则进一步根据最后一个statistics,来判断报警器的发展状态的趋势;
    """
    elif unknown or continuous:
        """
        如果当前状态为UNKNOWN,则根据趋势改变状态,即观察最后一个statistics,
        如果它为true,说明最后一个statistics符合触发报警器的条件,则说明报警器有转换为ALARM状态的趋势,
        如果它为false,说明最后一个statistics不符合触发报警器的条件,则说明报警器有转换为OK状态的趋势;
        """
        trending_state = evaluator.ALARM if compared[-1] else evaluator.OK
            
        """
        如果当前报警器的状态为'insufficient data',则采用trending_state作为报警器的状态;
        """
        state = trending_state if unknown else alarm.state
        reason,state)
        """
        实现刷新报警器的状态为指定状态;
        """
        self._refresh(alarm,reason_data)
方法小结:

根据statistics是否满足触发报警器条件,来更新报警器报警状态(alarm或ok);
1.验证所有的statistics是否满足触发报警器的条件;
* 所有的statistics均满足触发报警器条件;
* 所有的statistics均不满足触发报警器条件;
* 报警器的数据状态为'insufficient data'(数据不充足);
2.如果所有的statistics均满足报警条件,则说明需触发报警,报警器的状态设置为'alarm';
3.如果所有的statistics均不满足报警条天,则说明报警器处于正常状态,报警器的状态设置为'ok';
4.如果当前报警器的状态为'insufficient data'(数据不充足),则根据最后一个statistics,来判断报警器的发展状态的趋势,进而确定报警器的报警状态;
* 如果最后一个statistics符合触发报警器的条件,则说明报警器有转换为ALARM状态的趋势,则设置报警器的报警状态为alarm;
* 如果最后一个statistics不符合触发报警器的条件,则说明报警器有转换为OK状态的趋势,则设置报警器的报警状态为ok;


4 def evaluate(self,alarm)

这个方法最终实现单一报警器状态的评估操作,上面的方法实际上都被这个方法调用,为单一报警器的评估实现了若干操作(具体实现可以见代码注释);

def evaluate(self,alarm):
    """
    根据报警器获取指定的metrics的结果statistics列表;
    根据statistics是否满足触发报警器条件,来更新报警器的状态;
    """
    if not self.within_time_constraint(alarm):
        LOG.debug(_('Attempted to evaluate alarm %s,but it is not '
                    'within its time constraint.') % alarm.alarm_id)
        return

    # 参照alarm的属性,alarm.rule['query']是
    # Metadata.user_Metadata.server_group == WebServerGroup;
    # 该方法计算evaluate操作的时间段;
    # 在query的内容添加时间段为[start,now]的条件,
    # 最后返回更改后的query;
    query = self._bound_duration(
            alarm,alarm.rule['query']
    )

    """
    _statistics:获取query和meter_name(meter_name=alarm.rule['meter_name'])指定的监控统计数据列表;
    通过客户端通过HTTP协议GET方法获取符合查询条件的statistics列表;
    最终的返回结果为meter_name指定的metrics的结果statistics列表;
    对获取的监控数据列表进行数据的除错处理;
    """
    statistics = self._sanitize(
            alarm,self._statistics(alarm,query)
    )

    # _sufficient:确保报警器评估具有足够的仲裁数据(根据statistics数目);
    # _sufficient方法用来判断返回的查询结果statistics是否够支持evaluate,其中的quorum为statistics的最小长度,默认为1:
          
    """
    确保报警器评估具有足够的数据(仲裁人数);
    根据statistics是否满足触发报警器条件,来更新报警器的报警状态(alarm或ok);
    """
    if self._sufficient(alarm,statistics):
        def _compare(stat):
            op = COMPARATORS[alarm.rule['comparison_operator']]
            value = getattr(stat,alarm.rule['statistic'])  
            """
            获取规定的触发报警器的数值限制;
            """
            limit = alarm.rule['threshold']
            LOG.debug(_('comparing value %(value)s against threshold'
                        ' %(limit)s') %
                      {'value': value,'limit': limit})
            return op(value,limit)

        """
        根据statistics是否满足触发报警器条件,来更新报警器的报警状态(alarm或ok);
        """
        self._transition(alarm,map(_compare,statistics))

猜你在找的设计模式相关文章