kubernetes/www/master/shared/js/modules/services/cAdvisor.js
BC Broussard 2f43fc72db Update Web UI Bar Gauge Graphs
- Changed file system abbreviation from 'FS' to Filesystem
- Made chart height dynamic and incorporated legend height change into the master code/datafile.go binary
- Updated the max colors for the graph
- Realigned graph numbers
2015-06-26 13:52:08 -07:00

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/v1/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;
}
});
})();