Custom business rule for HI

How to calculate Average Value for CI monitored by multiple SiS monitors

Consider the following scenario: you are using SiS to monitor a CI, and the Service Health HI is impacted by SiS metrics (note: this is NOT relevant in case you send Events from SiS to impact Service Health).
If the HI is impacted by 1 measurement, then the HI will have Value, but when you have more than 1 measurement then the HI will show “Multiple Values”. The reason for this behavior is that Service Health cannot guarantee that all measurements have the same unit.

But what happens if you know that all monitors have the same unit? An example for this can be URL monitor with Custom Topology (for example: Business Application CIT), from multiple SiS servers (you want to measure the response time from different locations).

The following document will explain the steps you need to take in order to display the average value in the Service Health HI, which is calculated from multiple SiS monitors (it doesn’t matter if the monitors are from the same server or not). This solution is using custom Rule API (a.k.a Groovy rules).

The step-by-step:

0)Pre-requisites – create (at least) 2 monitors impacting the same CI and then map SiS measurement to HI in both monitors. You can use OOTB HI or create your own custom HI.
In this example we will use “Business Application” and the OOTB HI “Bandwidth” for the “roundtrip time” measurement:

1)Add Business Rule – there are 2 ways to add custom business rule to Rules Repositories, both are well documented in “BSM Extensibility Guide”. In this example we will clone the OOTB rule “API Duration-Based Sample Rule”, but the groovy file approach is also valid.

  1. Open Service Health Admin > Repositories > Business Rules find “API Duration-Based Sample Rule”.
  2. Clone the rule and edit the cloned rule. You can also modify its name and give it meaningful name.
  3. In Rule Parameters,edit “KPI Calculation Script” and add the script as the default value. The groovy script is in Appendix A.
  4. In Rule Parameters, edit “Sample Fields” and add the fields as the default value. The fields can be found in Appendix B. Please note that not all the fields are used in the script. You can use them to enhance the script logic, or just to remove them (in case you have capacity concerns for your online engine).
  5. Optional: you can modify the default values for “duration” and “No data timeout” rule parameters which determines how many samples will be part of the rule calculation. It is recommended that they will match the SiS monitor frequency + 90 seconds (to recover from network latency issues).
  6. Optional: you can define default Thresholds for the rule, so the HI will have status from the average value.

2)Add HI Assignment – in order to get the HI assigned automatically, we need to add HI assignment rule, otherwise the OOTB SiS assignment will take place (which will assign the OOTB “SiteScope Worst status rule”).

  1. In Service Health Admin > Assignments > HI Assignments, select the CIT which you monitor will report (in this case Business Application).
  2. Add new HI assignment and give it meaningful name.
  3. Condition
  4. In the “Monitored By” select “SiteScope” from the dropdown list.
  5. Add property condition, on any attribute you want to use. In this example, we are looking for Business Application’s Description in order to add the HI with the new rule. Please note that you cannot leave this empty, otherwise BSM won’t let you save the assignment due to conflict with the OOTB SiS assignment.
  1. Task
  2. Add new HI configuration.
  3. Select the HI you want to assign. Make sure it is the same HI as you used in the SiS monitor metric to HI mapping (from step 0).
  4. Select the business rule you created in step 1.
  5. Set Priority to 1000 (this is needed to override default HI assignment which has priority of 0).
  6. Add selector expression like this (note the correct type):
  7. Optional – you can adjust rule thresholds (to determine HI status based on the average value) in this step (or in step 1).

3)Add KPI Assignment – this step is optional, but if you are using custom HI or HI which is not mapped to KPI, you should perform this step in order to see how your HI impacts a KPI.
Note: the KPI Assignment’s condition doesn’t need to have the property condition as HI Assignment, since KPI Assignment is triggered by CI answering the condition together with assigned HIs.

4)Update CI attribute – in order for the HI Assignment to work, you need to modify the CI’s attribute to match the condition as you set in HI Assignment’s condition.
Note: you can use Enrichment rule to automatically set the attribute, for example: using the SiS monitor for filtering (maybe using the SiS monitor name).
In this case, we will just modify the Business Application CI in IT Universe Manager:

The result:

Appendix A – the groovy script:

logger.debug("start");

log.debug("number of samples = " + samples.size());

Map measIdsToSamples = new HashMap();

samples.each {Sample aSample ->

logger.debug("handling sample");

if (measIdsToSamples.containsKey(aSample.u_iMeasurementId)) {

// already got sample for this measurement, keep the more recent sample

logger.debug("not first sample for measurement Id=" + aSample.u_iMeasurementId);

Sample currentSample = measIdsToSamples.get(aSample.u_iMeasurementId);

if (currentSample.time_stamp <= aSample.time_stamp) {

// found more recent sample

logger.debug("found recent sample");

measIdsToSamples.put(aSample.u_iMeasurementId, aSample);

}

}

else { // first sample for this measId

logger.debug("first sample for measurement Id=" + aSample.u_iMeasurementId);

measIdsToSamples.put(aSample.u_iMeasurementId, aSample);

}

}

if (measIdsToSamples.size() > 0) {

// we have samples, perform average

defsumOfValues = 0;

measIdsToSamples.values().each {Sample aSample ->

logger.debug("adding sample with value = " + aSample.dValue);

sumOfValues = Utils.sum(sumOfValues, aSample.dValue);

}

logger.debug("total value = " + sumOfValues + ", num of measurements = " + measIdsToSamples.size() + ", kpi value = " + Utils.divide(sumOfValues, measIdsToSamples.size()));

kpi.value = Utils.divide(sumOfValues, measIdsToSamples.size());

}

logger.debug("end");

Appendix B – sample fields:

"u_iQuality", "sampleType", "frequency", "cfg_frequency", "u_iStatus", "u_iMeasurementId", "u_iSessionId", "dValue", "szMeasurementName","time_stamp"