Name

sn_app_insights.MetricTriggerUtils

Description

No description available

Script

var MetricTriggerUtils = Class.create();
MetricTriggerUtils.prototype = {
  initialize: function() {
  	this.JOB_ID = '8eccc01723612010fb0c949e27bf6594';
  },
  
  /*
   * Create a condition using the supplied JSON object
   * @param conditionObj JSON: Object containing all information needed for trigger creation
   *
   * Example JSON: {
  	 name: Name of conditional trigger
  	 triggers: [{
  		 metric: sys_id of metric to create trigger on (String)
  		 threshold: Threshold for the trigger (Number)
  		 sustained_for: How long the metric should be sustained for in minutes (Number)
  		 operation: Which comaprison operation should be used, e.g. lt, gt, lte (String)
  		 condition: The condition operation associated with this trigger, e.g. ^, ^OR (String)
  	 }]
   }
   */
  createThreshold: function (thresholdObj) {		
  	var gr = new GlideRecordSecure('sn_app_insights_trigger_condition');
  	gr.setValue('name', thresholdObj.name);
  	var id = gr.insert();
  	
  	if (!id)
  		return id;
  	
  	this._createOrUpdateTriggers(thresholdObj.triggers, id);
  	var condition = this._getConditionForThreshold(thresholdObj.triggers);
  	
  	gr.get(id);
  	gr.setValue('condition', condition);
  	gr.update();
  	
  	return id;
  },
  
  updateThreshold: function (thresholdObj, thresholdId) {
  	var gr = new GlideRecordSecure('sn_app_insights_trigger_condition');
  	if (!gr.get(thresholdId))
  		return;
  	
  	var triggerIds = thresholdObj.triggers.map(function (trigger) {
  		return trigger.id;
  	});
  	
  	this._deleteUnusedTriggers(thresholdId, triggerIds);
  	this._createOrUpdateTriggers(thresholdObj.triggers, thresholdId);
  	var condition = this._getConditionForThreshold(thresholdObj.triggers);
  	gr.setValue('condition', condition);
  	if (thresholdObj.name)
  		gr.setValue('name', thresholdObj.name);
  	return gr.update();
  },
  
  deleteThreshold: function (thresholdId) {
  	var gr = new GlideRecordSecure('sn_app_insights_trigger_condition');
  	gr.get(thresholdId);
  	
  	return gr.deleteRecord();
  },
  
  //Deletes trigger records that no longer exist in the new condition for a threshold
  _deleteUnusedTriggers: function (thresholdId, triggerIds) {
  	var grTrigger = new GlideRecordSecure('sn_app_insights_metric_trigger');
  	grTrigger.addQuery('condition', thresholdId);
  	grTrigger.addQuery('sys_id', 'NOT IN', triggerIds.join(','));
  	grTrigger.deleteMultiple();
  },
  
  /*
   * Updates triggers if they already exist. This is a way to re-use triggers instead of
   * deleting them all on every update and re-creating them.
   */
  _createOrUpdateTriggers: function (triggers, thresholdId) {
  	triggers.forEach(function (trigger) {
  		var gr = new GlideRecordSecure('sn_app_insights_metric_trigger');
  		
  		var shouldUpdate = false;
  		
  		if (trigger.id && gr.get(trigger.id))
  			shouldUpdate = true;
  			
  		gr.setValue('metric', trigger.metric);
  		gr.setValue('threshold', trigger.threshold);
  		
  		var gdt = new GlideDateTime();
  		if (!isNaN(Number(trigger.sustained_for)))
  			gdt.setValue(Number(trigger.sustained_for) * 60 * 1000);
  		else
  			gdt.setValue(0);
  		
  		gr.setValue('sustained_for', gdt);
  		gr.setValue('operation', trigger.operation);
  		gr.setValue('condition', thresholdId);
  		
  		if (shouldUpdate)
  			gr.update();
  		else
  			trigger.id = gr.insert();
  	});
  },
  
  evaluateCondition: function (thresholdGr) {
  	var metricConditionUtils = new MetricConditionUtils();
  	var parsedCondition = metricConditionUtils.parseCondition(thresholdGr);
  	
  	for (i = 0; i < parsedCondition.length; ++i) {
  		var evaluation = metricConditionUtils.evaluateInnerCondition(parsedCondition[i]);
  		if (evaluation.result)
  			return evaluation;
  	}
  	
  	return {evaluation: false};
  },
  
  /*
   * Creates an object with metrics and their values to be used by notification flows
   * 
   * @param parentGr GlideRecord: Top level metric trigger log
   * @return JSON: Object with child metric trigger logs and relevant display values
   *
   * Example JSON:  [
    {
     	id: ID of metric trigger log record,
      value: Value of metric as measured,
      record: Display value of record for which the value is associated,
      metric: Display value of associated metric
    },
    ...
  ]
   */
  
  getProcessedLogs: function(parentGr) {
  	var gr = this.getChildMetricLogs(parentGr);
  	var logsObj = [];
  	while (gr.next()) {
  		logsObj.push({
  			id: gr.getUniqueValue(),
  			value: Number(gr.getValue('value')).toFixed(2),
  			metric: gr.getDisplayValue('metric'),
  			record: gr.getDisplayValue('record')
  		});
  	}
  	return logsObj;
  },
  
  getChildMetricLogs: function(parentGr) {
  	var gr = new GlideRecord('sn_app_insights_metric_trigger_log');
  	gr.addQuery('parent', parentGr.getUniqueValue());
  	gr.query();
  	return gr;
  },
  
  /*
   * Get metric trigger records for a particular metric
   * @param metricGr GlideRecord metric record
   * @return Array of threshold values and their labels (i.e. the name of their parent conditions)
   */
  getThresholdsForMetric: function (metricName, tableName) {		
  	var gr = new GlideRecord('sn_app_insights_metric_trigger');
  	gr.addQuery('metric.element', metricName);
  	gr.addQuery('metric.name', tableName);
  	gr.query();
  	var thresholds = [];
  	while (gr.next()) {
  		thresholds.push({
  			label: gr.condition.name,
  			value: parseInt(gr.getValue('threshold'))
  		});
  	}
  	return thresholds;
  },
  
  getParsedCondition: function (id) {
  	var grThreshold = new GlideRecordSecure('sn_app_insights_trigger_condition');
  	if (!grThreshold.get(id))
  		return {};
  	
  	var triggers = new MetricConditionUtils().parseConditionExternal(grThreshold);
  	
  	triggers.forEach(function (trigger) {
  		var grTrigger = new GlideRecordSecure('sn_app_insights_metric_trigger');
  		if (!grTrigger.get(trigger.id))
  			return;
  		
  		trigger.metric = {value: grTrigger.getValue('metric'), displayValue: grTrigger.metric.getDisplayValue()};
  		trigger.threshold = grTrigger.getValue('threshold');
  		trigger.sustained_for = String(
  			new GlideDateTime(grTrigger.getValue('sustained_for'))
  			.getNumericValue() / 1000 / 60
  		);
  		trigger.operation = grTrigger.getValue('operation');
  	});
  			
  	var result = {};
  	result.triggers = triggers;
  	result.flow = grThreshold.getValue('flow');
  	result.id = id;
  	result.name = grThreshold.getValue('name');
  	
  	return result;
  },
  
  _getConditionForThreshold: function (triggers) {
  	var condition = '';
  	triggers.forEach(function (trigger) {
  		condition += (trigger.condition ? trigger.condition : '') + trigger.id;
  	});
  	return condition;
  },

  type: 'MetricTriggerUtils'
};

Sys ID

48e7849523c12010fb0c949e27bf651e

Offical Documentation

Official Docs: