Mointor Rule是BAC数据来源的起点,数据传到BAC的BUS后都是通过Monitor Rule取得。所以重要性就不用说了。
以下是对FieldToValueRule的分析,其他的Rule大致流程也差不多了。
1、 initRuleIfNeeded 方法的主要作用就是建立Accumulator,Accumulator可以看做是一个容器,用于传递Samples。在该方法内部
1.1:判断KPI是否已经初始化
kpi.getTransientValue("__ACT_WAS_INITIALIZED");//判断KPI是否初始化,是否初始化的标准就是KPI是否包含Accumulator
1.2:若没有初始化,通过调用LeafRule的internalInit(access, node, kpi)方法,对KPI进行初始化。初始化过程如下:通过新建一个Accumulator,初始化maxCount=1,并调用kpi.setStateValue("__ACT_ACCUMULATOR", accumulator);对Accumulator进行保存。注意:在这里其实是建立的SampleBasedAccumulator(Accumulator子类)
1.3、完成KPI初始化过后,调用init(access, node, kpi)做进一步的初始化工作,但是在FieldToValueRule中,这里啥也不干。
1.4
kpi.setTransientValue("__ACT_WAS_INITIALIZED", Boolean.TRUE);//这行就不需多解释了 kpi.setTransientValue("__ACT_INITIALIZED_ON", new Long(access.getDataEndTime()));//保存KPI初始化时间
1.5、如果在调用initRuleIfNeeded 之前已经完成了初始化,那么initRuleIfNeeded 啥也不干。
2、完成1过后调用clearPreviousStatus(kpi),清理KPI历史数据。
objective.removeTransientValue("__ACT_LastStatus"); objective.removeResultValue("is_no_data_status");
3、做SLM的Downtime检查,对FieldToValueRule来说,没有什么用,跳过
4、calculate方法调用。因为LeafRule重写了该方法,所以这里实际上是调用LeafRule的calculate方法。
该方法的具体逻辑如下:
4.1 、
Accumulator accumulator = getAccumulator(kpi); 这里会尝试获得和KPI相关的Accumulator
4.2、调用processSamples,
4.2.1 若有Sample传到BAC,那么会把所有的sample取出来,包装成ExtractedSample,并添加到新建的
ExtractedSampleContainer中。具体怎么取的呢?参考上一篇帖子。然后对取出的sample做过
滤, 具体对FieldToValueRule来说,过滤的实现为空,也就是说不过滤任何sample。过滤过
后, 就把 所有的sample加入到4.1中的Accumulator 中。
4.2.2 若此时没有sample传到BAC,调用accumulator.removeSamplesIfNeeded(access);来删除旧的
sample。但是对FieldToValueRule来说在会保留至少一个sample,即最新的。对其他和时间相
关 的 Rule,会删除所有的超时sample。
4.3 取出最新的sample,如果不为空,通过对比KPI的“LAST_TIMESTAMP”和该sample的“time_stamp”
决定是否更新“LAST_TIMESTAMP”
kpi.setStateValue("LAST_TIMESTAMP", new Long(latestTimestamp));
4.4 通过accumulator.removeSamplesIfNeeded(access)删除多余sample,和上面分析的一样,保留最新的
4.5 判断是否超时,若超时就安无数据处理。【?】同时 calculate方法结束,返回execute方法。
4.6 若不超时,调用父类calculate。在父类calculate中调用doPreCalculation,同样,在FieldToValueRule
啥 也不干。
4.7 调用calculateKpi。由于该方法会被LeafRule重写,所有在这里调用的是LeafRule的calculateKpi,而在
LeafRule中有个重载的calculateKpi方法,而该重载的calculateKpi方法一般会再次被子类重写,
所以最后真正调用的是FieldToValueRule的calculateKpi。不过在调用之前会把会通过
accumulator获得ExtractedSampleContainer,并把后者当做参数传入FieldToValueRule的
calculateKpi中,最后在重写的calculateKpi方法中,我们把需要的值取出来,并以
"Result"的形式保存到KPI的RuleObjective中
4.8 完成值的保存过后,通过calculateValueForObjective回去保存的值,这个方法也需要重写。
4.9 利用evaluateObjective(objective, objectiveValue)把值和设置的阈值对比,计算出状态结果
4.10 利用updateStatus(access, objective, newStatus)跟新KPI状态
objective.setResultValue("status", status); 若状态有变,同时更新KPI的"LastStatusChange"属性 objective.setResultValue("LastStatusChange", new Long(access.getDataEndTime()));
4.11 调用doPostCalculation,同样在这里啥也不做 。到这里calculate算是执行完了。返回execute
5、 执行完execute后,主要的取值逻辑也执行完了,剩下的就是对结果、状态做进一步处理,
比如调用handleAlerts(access, node, kpi);处理告警 等的
FieldToValueRule——>DashboardSampleRule——>SampleRule——>LeafRule——>BaseRule
从继承关系来看,一切的Rule都是集成之BaseRule,BaseRule规定了取值(计算)的一般流程,它会暴露execute方法给外部调用,而在execute方法内部通过调用BaseRule或者其子类的其他方法完成了计算。我们从execute方法开始来分析BAC的取值(计算)过程。
1、 initRuleIfNeeded 方法的主要作用就是建立Accumulator,Accumulator可以看做是一个容器,用于传递Samples。在该方法内部
1.1:判断KPI是否已经初始化
kpi.getTransientValue("__ACT_WAS_INITIALIZED");//判断KPI是否初始化,是否初始化的标准就是KPI是否包含Accumulator