
remove node modules make new data file for web ui initial commit of dashboard switch back to non SSL request move port splitting to common place; add to node resource location Signed-off-by: Patrick Reilly <patrick@kismatic.io> various path fixes make svg path relative work around missing mime type Signed-off-by: Patrick Reilly <patrick@kismatic.io> fix paths fix karma path remove bad protractor test
196 lines
6.9 KiB
JavaScript
196 lines
6.9 KiB
JavaScript
(function() {
|
|
"use strict";
|
|
|
|
angular.module('kubernetesApp.services')
|
|
.service('cAdvisorService', function($http, $q, ENV) {
|
|
var _baseUrl = function(minionIp) {
|
|
var minionPort = ENV['/']['cAdvisorPort'] || "8081";
|
|
var proxy = ENV['/']['cAdvisorProxy'] || "/api/v1beta2/proxy/nodes/";
|
|
|
|
return proxy + minionIp + ':' + minionPort + '/api/v1.0/';
|
|
};
|
|
|
|
this.getMachineInfo = getMachineInfo;
|
|
|
|
function getMachineInfo(minionIp) {
|
|
var fullUrl = _baseUrl(minionIp) + 'machine';
|
|
var deferred = $q.defer();
|
|
|
|
// hack
|
|
$http.get(fullUrl).success(function(data) {
|
|
deferred.resolve(data);
|
|
}).error(function(data, status) { deferred.reject('There was an error') });
|
|
return deferred.promise;
|
|
}
|
|
|
|
this.getContainerInfo = getContainerInfo;
|
|
// containerId optional
|
|
function getContainerInfo(minionIp, containerId) {
|
|
containerId = (typeof containerId === "undefined") ? "/" : containerId;
|
|
|
|
var fullUrl = _baseUrl(minionIp) + 'containers' + containerId;
|
|
var deferred = $q.defer();
|
|
|
|
var request = {
|
|
"num_stats": 10,
|
|
"num_samples": 0
|
|
};
|
|
|
|
$http.post(fullUrl, request)
|
|
.success(function(data) { deferred.resolve(data); })
|
|
.error(function() { deferred.reject('There was an error') });
|
|
return deferred.promise;
|
|
}
|
|
|
|
this.getDataForMinion = function(minionIp) {
|
|
var machineData, containerData;
|
|
var deferred = $q.defer();
|
|
|
|
var p = $q.all([getMachineInfo(minionIp), getContainerInfo(minionIp)])
|
|
.then(
|
|
function(dataArray) {
|
|
machineData = dataArray[0];
|
|
containerData = dataArray[1];
|
|
|
|
var memoryData = parseMemory(machineData, containerData);
|
|
var cpuData = parseCpu(machineData, containerData);
|
|
var fsData = parseFilesystems(machineData, containerData);
|
|
deferred.resolve({
|
|
memoryData: memoryData,
|
|
cpuData: cpuData,
|
|
filesystemData: fsData,
|
|
machineData: machineData,
|
|
containerData: containerData
|
|
});
|
|
|
|
},
|
|
function(errorData) { deferred.reject(errorData); });
|
|
|
|
return deferred.promise;
|
|
};
|
|
|
|
// Utils to process cadvisor data
|
|
function humanize(num, size, units) {
|
|
var unit;
|
|
for (unit = units.pop(); units.length && num >= size; unit = units.pop()) {
|
|
num /= size;
|
|
}
|
|
return [num, unit];
|
|
}
|
|
|
|
// Following the IEC naming convention
|
|
function humanizeIEC(num) {
|
|
var ret = humanize(num, 1024, ["TiB", "GiB", "MiB", "KiB", "Bytes"]);
|
|
return ret[0].toFixed(2) + " " + ret[1];
|
|
}
|
|
|
|
// Following the Metric naming convention
|
|
function humanizeMetric(num) {
|
|
var ret = humanize(num, 1000, ["TB", "GB", "MB", "KB", "Bytes"]);
|
|
return ret[0].toFixed(2) + " " + ret[1];
|
|
}
|
|
|
|
function hasResource(stats, resource) { return stats.stats.length > 0 && stats.stats[0][resource]; }
|
|
|
|
// Gets the length of the interval in nanoseconds.
|
|
function getInterval(current, previous) {
|
|
var cur = new Date(current);
|
|
var prev = new Date(previous);
|
|
|
|
// ms -> ns.
|
|
return (cur.getTime() - prev.getTime()) * 1000000;
|
|
}
|
|
|
|
function parseCpu(machineInfo, containerInfo) {
|
|
var cur = containerInfo.stats[containerInfo.stats.length - 1];
|
|
var results = [];
|
|
|
|
var cpuUsage = 0;
|
|
if (containerInfo.spec.has_cpu && containerInfo.stats.length >= 2) {
|
|
var prev = containerInfo.stats[containerInfo.stats.length - 2];
|
|
var rawUsage = cur.cpu.usage.total - prev.cpu.usage.total;
|
|
var intervalInNs = getInterval(cur.timestamp, prev.timestamp);
|
|
|
|
// Convert to millicores and take the percentage
|
|
cpuUsage = Math.round(((rawUsage / intervalInNs) / machineInfo.num_cores) * 100);
|
|
if (cpuUsage > 100) {
|
|
cpuUsage = 100;
|
|
}
|
|
}
|
|
|
|
return {
|
|
cpuPercentUsage: cpuUsage
|
|
};
|
|
}
|
|
|
|
function parseFilesystems(machineInfo, containerInfo) {
|
|
var cur = containerInfo.stats[containerInfo.stats.length - 1];
|
|
if (!cur.filesystem) {
|
|
return;
|
|
}
|
|
|
|
var filesystemData = [];
|
|
for (var i = 0; i < cur.filesystem.length; i++) {
|
|
var data = cur.filesystem[i];
|
|
var totalUsage = Math.floor((data.usage * 100.0) / data.capacity);
|
|
|
|
var f = {
|
|
device: data.device,
|
|
filesystemNumber: i + 1,
|
|
usage: data.usage,
|
|
usageDescription: humanizeMetric(data.usage),
|
|
capacity: data.capacity,
|
|
capacityDescription: humanizeMetric(data.capacity),
|
|
totalUsage: Math.floor((data.usage * 100.0) / data.capacity)
|
|
};
|
|
|
|
filesystemData.push(f);
|
|
}
|
|
return filesystemData;
|
|
}
|
|
|
|
var oneMegabyte = 1024 * 1024;
|
|
var oneGigabyte = 1024 * oneMegabyte;
|
|
|
|
function parseMemory(machineInfo, containerInfo) {
|
|
if (containerInfo.spec.has_memory && !hasResource(containerInfo, "memory")) {
|
|
return;
|
|
}
|
|
|
|
// var titles = ["Time", "Total", "Hot"];
|
|
var data = [];
|
|
for (var i = 0; i < containerInfo.stats.length; i++) {
|
|
var cur = containerInfo.stats[i];
|
|
|
|
var elements = [];
|
|
elements.push(cur.timestamp);
|
|
elements.push(cur.memory.usage / oneMegabyte);
|
|
elements.push(cur.memory.working_set / oneMegabyte);
|
|
data.push(elements);
|
|
}
|
|
|
|
// Get the memory limit, saturate to the machine size.
|
|
var memory_limit = machineInfo.memory_capacity;
|
|
if (containerInfo.spec.memory.limit && (containerInfo.spec.memory.limit < memory_limit)) {
|
|
memory_limit = containerInfo.spec.memory.limit;
|
|
}
|
|
|
|
var cur = containerInfo.stats[containerInfo.stats.length - 1];
|
|
|
|
var r = {
|
|
current: {
|
|
memoryUsage: cur.memory.usage,
|
|
workingMemoryUsage: cur.memory.working_set,
|
|
memoryLimit: memory_limit,
|
|
memoryUsageDescription: humanizeMetric(cur.memory.usage),
|
|
workingMemoryUsageDescription: humanizeMetric(cur.memory.working_set),
|
|
memoryLimitDescription: humanizeMetric(memory_limit)
|
|
},
|
|
historical: data
|
|
};
|
|
|
|
return r;
|
|
}
|
|
});
|
|
})();
|