Name
sn_app_insights.MultiMetricDataRetriever
Description
No description available
Script
var MultiMetricDataRetriever = Class.create();
MultiMetricDataRetriever.prototype = {
initialize: function() {
this.X_AXIS = "x";
this.X_AXIS_KEY = "timeStamp";
this.Y_AXIS = "y";
this.TYPE = "type";
this.LINE_TYPE = "line";
this.LABEL = "label";
this.dataFromMetricBase = [];
this.SYS_CLUSTER_STATE = "sys_cluster_state";
},
getMultiMetricDataPayload: function(reqMetrics, secondsInTimeWindow) {
var start = new GlideDateTime();
start.addSeconds(-1 * secondsInTimeWindow);
var graphPayload = {};
var metricObjects = this._getMetricObjects(reqMetrics);
this._readyDataFromMetricBase(metricObjects, secondsInTimeWindow);
graphPayload.seriesConfig = this._seriesConfig(metricObjects, this.dataFromMetricBase);
graphPayload.seriesData = this._seriesData(this.dataFromMetricBase);
var thresholdUtils = new ThresholdUtils();
graphPayload["thresholdConfig"] = thresholdUtils.buildThresholdConfig();
graphPayload["thresholdData"] = this._addQueueDepthLimitThreshold(reqMetrics);
var annotationsDataUtils = new AnnotationsDataUtils();
graphPayload["annotationsConfig"] = annotationsDataUtils._getAnnotationsConfig();
var annotationsData = annotationsDataUtils._getAnnotationsData(start);
graphPayload["annotationsData"] = annotationsData.data;
graphPayload["annotationsMetadata"] = annotationsData.counts;
return graphPayload;
},
_readyDataFromMetricBase: function(reqMetrics, secondsInTimeWindow) {
for (var i = 0; i < reqMetrics.length; ++i)
this.dataFromMetricBase.push(this._getDataForMetric(reqMetrics[i], secondsInTimeWindow, reqMetrics[i].averageMetrics));
},
_getDataForMetric: function(metric, secondsInTimeWindow, averageMetrics) {
var end = new GlideDateTime();
var start = new GlideDateTime(end);
start.addSeconds(-1 * secondsInTimeWindow);
var metricSubjects = new GlideRecord(metric.tableName);
if (metric.tableName == this.SYS_CLUSTER_STATE)
metricSubjects.addQuery("status", "online");
metricSubjects.query();
var resamplePeriodDuration;
if (metric.tableName == this.SYS_CLUSTER_STATE) {
var scheduledJob = new GlideRecord("sysauto_script");
scheduledJob.get("8c94b336c37310107f5633f6bb40dddc");
resamplePeriodDuration = new GlideDuration(scheduledJob.run_period.dateNumericValue());
} else
resamplePeriodDuration = new GlideDuration(5 * 60 * 1000);
var transformer = new sn_clotho.Transformer(metricSubjects);
switch (metric.aggregate) {
case 'average':
transformer.metric(metric.metricName).avg().resample("AVG", resamplePeriodDuration);
break;
case 'maximum':
transformer.metric(metric.metricName).max().resample("MAX", resamplePeriodDuration);
break;
case 'minimum':
transformer.metric(metric.metricName).min().resample("MIN", resamplePeriodDuration);
break;
default:
transformer.metric(metric.metricName).sum().resample("AVG", resamplePeriodDuration);
}
var resultArray = transformer.execute(start, end).toArray();
return resultArray;
},
_seriesConfig: function(reqMetrics, resultArray) {
var seriesConfig = {};
for (var i = 0; i < resultArray.length; i++) {
var singleLineConfig = {};
singleLineConfig[this.X_AXIS] = this.X_AXIS_KEY;
singleLineConfig[this.Y_AXIS] = this.Y_AXIS + i;
singleLineConfig[this.TYPE] = this.LINE_TYPE;
singleLineConfig[this.LABEL] = reqMetrics[i].label;
seriesConfig[reqMetrics[i].metricName] = singleLineConfig;
}
return seriesConfig;
},
_seriesData: function(resultArray) {
if (resultArray.length == 0 )
return [];
var index = 0;
//find first non zero length second dimension
for (index; index < resultArray.length; index++) {
if(resultArray[index].length != 0)
break;
}
if(index >= resultArray.length)
return [];//no series had entries
var seriesData = this._populateSeriesDataSkeletonWithTimeStamps(resultArray[index][0]);
for (var lineNumber = 0; lineNumber < resultArray.length; lineNumber++) {
if (!resultArray[lineNumber] || !resultArray[lineNumber][0])
continue;
var valuesOfSingleLine = resultArray[lineNumber][0].getValues();
for (var dataPointIndex = 0; dataPointIndex < seriesData.length; dataPointIndex++) {
var pointInTime = seriesData[dataPointIndex];
// The NaN object gets turned to a string when it exists in the return, but null doesn't. So
// make all NaN objects null objects so the front-end can process it correctly.
var metricValue = valuesOfSingleLine[dataPointIndex];
pointInTime[this.Y_AXIS + lineNumber] = isNaN(metricValue) ? null : valuesOfSingleLine[dataPointIndex];
}
}
return seriesData;
},
_populateSeriesDataSkeletonWithTimeStamps: function(singleResultArray) {
// Create new gdt so we don't modify the original in the result
var indexDateTime = new GlideDateTime(singleResultArray.getStart());
var seriesDataSkeleton = [];
var valueArray = singleResultArray.getValues();
for (var i = 0; i < valueArray.length; i++) {
var localTimestamp = new GlideDateTime();
localTimestamp.setValue(indexDateTime.getDisplayValueInternal());
seriesDataSkeleton.push({
"timeStamp": localTimestamp.getNumericValue()
});
// Each value in the valueArray is separated from the previous value by an amount
// of time (ex: 300 seconds), which is the time period. So to get the time stamp for the
// next value, we need to increment by the period to get the time stamp related to the value
indexDateTime.addSeconds(singleResultArray.getPeriod());
}
return seriesDataSkeleton;
},
_getMetricObjects: function(reqMetrics) {
var metricsObject = [];
var graphSet = (reqMetrics).graphs;
graphSet.forEach(function(graph) {
var grMetric = new GlideRecord('sys_metric');
grMetric.addQuery('element', graph.metricName);
grMetric.addQuery('name', graph.tableName);
grMetric.query();
if (grMetric.next()) {
var label = grMetric.getValue('label');
label = label.replace(/^Metric - /, '');
metricsObject.push({
tableName: graph.tableName,
metricName: graph.metricName,
label: label,
aggregate: graph.aggregate,
});
}
});
return metricsObject;
},
_addQueueDepthLimitThreshold: function(reqMetrics) {
// NOTE: This method will only find the first metric with a defined depth limit,
// so it is not advised to mix multiple semaphore sets in a single reqMetrics object.
var thresholdData = [];
if (!reqMetrics)
return thresholdData;
var thresholdUtils = new ThresholdUtils();
var metrics = reqMetrics.graphs;
for (var i in metrics) {
var metricName = metrics[i]['metricName'];
thresholdUtils.addQueueDepthLimitThreshold(thresholdData, metricName);
if (thresholdData.length != 0)
return thresholdData;
}
return thresholdData;
},
type: 'MultiMetricDataRetriever'
};
Sys ID
b8486de8b7d1201080a89078ee11a962