vRealize Automation VM Performance Summary

Mit Begeisterung habe ich den Artikel VM Performance Summary with vRO von Ivaylo Ivanov verschlungen. Mein erster Gedanke war sofort den Workflow auch als vRealize Automation VM Performance Summary (XaaS) umzusetzen.

Dafür war gar nicht viel Anpassung notwendig, Ivaylo Ivanov hat sehr gut Arbeit bei dem vRealize Orchestrator Workflow geleistet.

Folgendes musste angepasst werden:

  • Ausgabe nicht mehr über User Interaktion sondern als Mail
  • Angepasstes Error Handling

Ausgabe des vRealize Automation VM Performance Summary:

vRealize Automation VM Performance Summary - eMail

Hinweiß:

Das Design der Mail ist nicht das endgültige, das überlasse ich lieber Leuten mit echtem HTML Know-How…

vRealize Automation VM Performance Summary Anforderung

Ich habe mich hierbei für eine Action entschieden. So hat der Enduser ohne zusätzliche Auswahl einen schnellen Zugriff und das Thema Sicherheit (nur Zugriff aus seine Elemente) ist auch kein Thema.

vRealize Automation VM Performance Summary - Request Action

Wie auch in dem originalen Workflow, muss der Zeitraum der Statistiken gewählt werden. Die Eingabe der Email Adresse ist für diesen Ansatz neu.

vRealize Automation VM Performance Summary - Request Input

vRealize Automation VM Performance Summary Workflow

vRealize Automation VM Performance Summary - Workflow

Der Hauptteil des vRealize Automation VM Performance Summary steckt in dem Script Task „Get and calculate„. Diesen habe ich nur um die Generierung des Email Body erweitert (siehe Markierung am Ende).

guestOS = sourceVM.config.guestFullName;
memory = sourceVM.summary.config.memorySizeMB;
memoryBallooned = sourceVM.summary.quickStats.balloonedMemory;
memorySwapped = sourceVM.summary.quickStats.swappedMemory;
memoryShared = sourceVM.summary.quickStats.sharedMemory;
memoryCompressed = sourceVM.summary.quickStats.compressedMemory;
vmtoolsStatus = sourceVM.guest.toolsRunningStatus;
cpuNum = sourceVM.summary.config.numCpu;
vmName = sourceVM.name;
pastTimeframePrint=pastTimeframeLocal;
var perfMgr = sourceVM.sdkConnection.perfManager;

/////////////
//CPU usage metric - percentage
var cpuUsageMetric = new VcPerfMetricId();
cpuUsageMetric.counterId = 2;
cpuUsageMetric.instance = "";

//CPU Ready time metric
var cpuReadyMetric = new VcPerfMetricId();
cpuReadyMetric.counterId = 12;
cpuReadyMetric.instance = "";

//Disk latency metric
var dskLatencyMetric = new VcPerfMetricId();
dskLatencyMetric.counterId = 133;
dskLatencyMetric.instance = "";

//Memory swap metric
var memUsgMetric = new VcPerfMetricId();
memUsgMetric.counterId = 24;
memUsgMetric.instance = "";

//Memory ballooned metric
var memBlnMetric = new VcPerfMetricId();
memBlnMetric.counterId = 90;
memBlnMetric.instance = "";

//Network usage metric
var netUsgMetric = new VcPerfMetricId();
netUsgMetric.counterId = 143;
netUsgMetric.instance = "";

//empty raw arrays
var cpuRdyRaw="";
var cpuUsgRaw="";
var dskLatRaw="";
var memUsgRaw="";
var memBlnRaw="";
var netUsgRaw="";

//data for the CPU perf metric queries
var myCpuPerfSpec = new VcPerfQuerySpec();
myCpuPerfSpec.entity = sourceVM.reference; // the source VM
myCpuPerfSpec.format = "csv"; //suppsosed to return string
myCpuPerfSpec.intervalId = 300; // past day
myCpuPerfSpec.metricId = [cpuReadyMetric, cpuUsageMetric]; //passing the array of metrics I'm want to query for

var queryCpuResult = perfMgr.queryPerf([myCpuPerfSpec]);

cpuRdyRaw = queryCpuResult[0].value[0].value;
cpuUsgRaw = queryCpuResult[0].value[1].value;

//data for the Disk perf metric queries
var myDskPerfSpec = new VcPerfQuerySpec();
myDskPerfSpec.entity = sourceVM.reference; // the source VM
myDskPerfSpec.format = "csv"; //suppsosed to return string
myDskPerfSpec.intervalId = 300; // past day
myDskPerfSpec.metricId = [dskLatencyMetric]; //passing the array of metrics I'm want to query for


var queryDskResult = perfMgr.queryPerf([myDskPerfSpec]);

dskLatRaw = queryDskResult[0].value[0].value;

//data for the Memory perf metric queries
var myMemPerfSpec = new VcPerfQuerySpec();
myMemPerfSpec.entity = sourceVM.reference; // the source VM
myMemPerfSpec.format = "csv"; //suppsosed to return string
myMemPerfSpec.intervalId = 300; // past day
myMemPerfSpec.metricId = [memUsgMetric, memBlnMetric]; //passing the array of metrics I'm want to query for

var queryMemResult = perfMgr.queryPerf([myMemPerfSpec]);

memUsgRaw = queryMemResult[0].value[0].value;
memBlnRaw = queryMemResult[0].value[1].value;

//data for the Net perf metric queries
var myNetPerfSpec = new VcPerfQuerySpec();
myNetPerfSpec.entity = sourceVM.reference; // the source VM
myNetPerfSpec.format = "csv"; //suppsosed to return string
myNetPerfSpec.intervalId = 300; // past day
myNetPerfSpec.metricId = [netUsgMetric]; //passing the array of metrics I'm want to query for


var queryNetResult = perfMgr.queryPerf([myNetPerfSpec]);

netUsgRaw = queryNetResult[0].value[0].value;

if ((cpuRdyRaw=="") || (cpuUsgRaw=="") || (dskLatRaw=="") || (memUsgRaw=="") || (memBlnRaw=="") || (netUsgRaw=="")) {
	throw "Missing data";
} else {
	var cpuRdyArrRaw = cpuRdyRaw.split(",").map(Number);
	var cpuUsgArrRaw = cpuUsgRaw.split(",").map(Number);
	for (var i = 0; i < cpuUsgArrRaw.length; i++) {
	    cpuUsgArrRaw[i] = cpuUsgArrRaw[i] / 100;
	}
	var dskLatArrRaw = dskLatRaw.split(",").map(Number);
	var memUsgArrRaw = memUsgRaw.split(",").map(Number);
	for (var i = 0; i < memUsgArrRaw.length; i++) {
	    memUsgArrRaw[i] = memUsgArrRaw[i] / 100;
	}
	var memBlnArrRaw = memBlnRaw.split(",").map(Number);
	for (var i = 0; i < memBlnArrRaw.length; i++) {
	    memBlnArrRaw[i] = memBlnArrRaw[i] / 1024;
	}
	var netUsgArrRaw = netUsgRaw.split(",").map(Number);
	
	var cpuRdyArr;
	var cpuUsgArr;
	var dskLatArr;
	var memUsgArr;
	var memBlnArr;
	var netUsgArr;
	
	switch (pastTimeframeLocal) {
		case "2 hours":
			cpuRdyArr = cpuRdyArrRaw.slice(-24);
			cpuUsgArr = cpuUsgArrRaw.slice(-24);
			dskLatArr = dskLatArrRaw.slice(-24);
			memUsgArr = memUsgArrRaw.slice(-24);
			memBlnArr = memBlnArrRaw.slice(-24);
			netUsgArr = netUsgArrRaw.slice(-24);
			break;
		case "4 hours":
			cpuRdyArr = cpuRdyArrRaw.slice(-48);
			cpuUsgArr = cpuUsgArrRaw.slice(-48);
			dskLatArr = dskLatArrRaw.slice(-48);
			memUsgArr = memUsgArrRaw.slice(-48);
			memBlnArr = memBlnArrRaw.slice(-48);
			netUsgArr = netUsgArrRaw.slice(-48);
			break;
		case "8 hours":
			cpuRdyArr = cpuRdyArrRaw.slice(-96);
			cpuUsgArr = cpuUsgArrRaw.slice(-96);
			dskLatArr = dskLatArrRaw.slice(-96);
			memUsgArr = memUsgArrRaw.slice(-96);
			memBlnArr = memBlnArrRaw.slice(-96);
			netUsgArr = netUsgArrRaw.slice(-96);
			break;
		case "12 hours":
			cpuRdyArr = cpuRdyArrRaw.slice(-144);
			cpuUsgArr = cpuUsgArrRaw.slice(-144);
			dskLatArr = dskLatArrRaw.slice(-144);
			memUsgArr = memUsgArrRaw.slice(-144);
			memBlnArr = memBlnArrRaw.slice(-144);
			netUsgArr = netUsgArrRaw.slice(-144);
			break;
		case "24 hours":
			cpuRdyArr = cpuRdyArrRaw;
			cpuUsgArr = cpuUsgArrRaw;
			dskLatArr = dskLatArrRaw;
			memUsgArr = memUsgArrRaw;
			memBlnArr = memBlnArrRaw;
			netUsgArr = netUsgArrRaw;
			break;
	}
	
	var cpuRdyMax = Math.max.apply(Math, cpuRdyArr);
	var cpuRdyMin = Math.min.apply(Math, cpuRdyArr);
	
	var cpuRdySum = 0;
	var cpuUsgSum = 0;
	var dskLatSum = 0;
	var memUsgSum = 0;
	var memBlnSum = 0;
	var netUsgSum = 0;
	for(var i = 0; i < cpuRdyArr.length; i++) {
	    cpuRdySum += cpuRdyArr[i];
		cpuUsgSum += cpuUsgArr[i]; //as both arrays will habe the same amount of elements
		dskLatSum += dskLatArr[i];
		memUsgSum += memUsgArr[i];
		memBlnSum += memBlnArr[i];
		netUsgSum += netUsgArr[i];
	}
	var cpuRdyAvg = cpuRdySum / cpuRdyArr.length;
	
	cpuRdyPercAvg = ((cpuRdyAvg / 3000) / cpuNum).toFixed(2);
	cpuRdyPercMax = ((cpuRdyMax / 3000) / cpuNum).toFixed(2);
	cpuRdyPercMin = ((cpuRdyMin / 3000) / cpuNum).toFixed(2);
	
	cpuUsgPercAvg = (cpuUsgSum / cpuUsgArr.length).toFixed(2);
	cpuUsgPercMax = Math.max.apply(Math, cpuUsgArr);
	cpuUsgPercMin = Math.min.apply(Math, cpuUsgArr);
	
	dskLatAvg = (dskLatSum / dskLatArr.length).toFixed(2);
	dskLatMax = Math.max.apply(Math, dskLatArr);
	dskLatMin = Math.min.apply(Math, dskLatArr);
	
	memUsgPercAvg = (memUsgSum / memUsgArr.length).toFixed(2);
	memUsgPercMax = Math.max.apply(Math, memUsgArr);
	memUsgPercMin = Math.min.apply(Math, memUsgArr);
	
	memBlnAvg = (memBlnSum / memBlnArr.length).toFixed(2);
	memBlnMax = Math.max.apply(Math, memBlnArr).toFixed(2);
	memBlnMin = Math.min.apply(Math, memBlnArr).toFixed(2);
	
	netUsgAvg = (netUsgSum / netUsgArr.length).toFixed(2);
	netUsgMax = Math.max.apply(Math, netUsgArr).toFixed(2);
	netUsgMin = Math.min.apply(Math, netUsgArr).toFixed(2);
}

var mail_body = "Selected VM: " + sourceVM.name + " \n " +
				"Guest OS configured: " + guestOS + " \n " +
				"VMtools status: " + vmtoolsStatus + " \n" +
				"Memory: " + memory + " MB \n " +
				"vCPUs: " + cpuNum + " \n \n " +
				"Memory allocation \n " +
				"Shared: " + memoryShared + " MB | Compressed: " + memoryCompressed + " KB | Ballooned: " + memoryBallooned + " MB | Swapped: " + memorySwapped + " MB \n \n " +
				"Data reported for the period of past " + pastTimeframePrint + " \n \n " +
				"1. CPU \n  " +
				"Ready time (per vCPU) \n " +
				"Min: " + cpuRdyPercMin + " % | Average: " + cpuRdyPercAvg + " % | Max: " + cpuRdyPercMax + " % \n " +
				"Usage \n " +
				"Min: " + cpuUsgPercMin + "  % | Average: " + cpuUsgPercAvg + " % | Max: " + cpuUsgPercMax + " % \n \n  " +
				"2. Memory \n " +
				"Usage \n " +
				"Min: " + memUsgPercMin + " % | Average: " + memUsgPercAvg + " % | Max: " + memUsgPercMax + " % \n " +
				"Ballooned \n " +
				"Min: " + memBlnMin + "  MB | Average: " + memBlnAvg + "  MB | Max: " + memBlnMax + "  MB \n \n " +
				"3. Disk latency \n " +
				"Min: " + dskLatMin + "  ms | Average: " + dskLatAvg + "  ms | Max: " + dskLatMax + "  ms \n \n" +
				"4. Network usage \n " +
				"Min: " + netUsgMin + "  KBps | Average: " + netUsgAvg + "  KBps | Max: " + netUsgMax + "  KBps \n  ";

 

Leave a Reply