Remove graphs page
This commit is contained in:
@@ -1,42 +0,0 @@
|
||||
<div class="content content-large">
|
||||
|
||||
<div class="row" ng-if="errorMessage">
|
||||
<br>
|
||||
<div class="alert alert-warning text-center">
|
||||
{{ errorMessage }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-left">
|
||||
<h2>Memory</h2>
|
||||
</div>
|
||||
|
||||
<div class="card card-large text-center">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h3>Apps</h3>
|
||||
<div style="width: 200px; height: 200px; margin: auto;">
|
||||
<canvas id="memoryUsageAppsChart" style="width: 200px; height: 200px;"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h3>System</h3>
|
||||
<div style="width: 200px; height: 200px; margin: auto;">
|
||||
<canvas id="memoryUsageSystemChart" style="width: 200px; height: 200px;"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h4 ng-show="activeApp === 'system'">System</h4>
|
||||
<h4 ng-show="activeApp !== 'system'">{{ activeApp.fqdn }}</h4>
|
||||
<br/>
|
||||
<canvas id="memoryAppChart" width="900" height="300"></canvas>
|
||||
<p>Memory consumption in MB.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,249 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/* global Chart:false */
|
||||
/* global asyncForEach:false */
|
||||
/* global angular:false */
|
||||
/* global $:false */
|
||||
|
||||
angular.module('Application').controller('GraphsController', ['$scope', '$location', 'Client', function ($scope, $location, Client) {
|
||||
Client.onReady(function () { if (!Client.getUserInfo().isAtLeastAdmin) $location.path('/'); });
|
||||
|
||||
$scope.memoryUsageSystem = [];
|
||||
$scope.memoryUsageApps = [];
|
||||
$scope.activeApp = null;
|
||||
$scope.memory = null;
|
||||
|
||||
$scope.errorMessage = '';
|
||||
|
||||
$scope.installedApps = Client.getInstalledApps();
|
||||
|
||||
// we use 1024 to match free -m output (which is not si units)
|
||||
function bytesToMegaBytes(value) {
|
||||
return (value/1024/1024).toFixed(2);
|
||||
}
|
||||
|
||||
// http://stackoverflow.com/questions/1484506/random-color-generator-in-javascript
|
||||
function getRandomColor() {
|
||||
var letters = '0123456789ABCDEF'.split('');
|
||||
var color = '#';
|
||||
for (var i = 0; i < 6; i++ ) {
|
||||
color += letters[Math.floor(Math.random() * 16)];
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
var colorIndex = 0;
|
||||
var colors = [ '#2196F3', '#3995b1', '#f0ad4e', '#ff4c4c' ];
|
||||
function getNextColor() {
|
||||
if (colors[colorIndex+1]) return colors[colorIndex++];
|
||||
return getRandomColor();
|
||||
}
|
||||
|
||||
$scope.setError = function (context, error) {
|
||||
$scope.errorMessage = 'Error loading ' + context + ' : ' + error.message;
|
||||
};
|
||||
|
||||
$scope.setMemoryApp = function (app, color) {
|
||||
$scope.activeApp = app;
|
||||
|
||||
var timePeriod = 12 * 60; // in minutes
|
||||
var timeBucketSize = 60; // in minutes
|
||||
|
||||
var target;
|
||||
if (app === 'system') target = 'summarize(sum(collectd.localhost.memory.memory-used, collectd.localhost.swap.swap-used), "' + timeBucketSize + 'min", "avg")';
|
||||
else target = 'summarize(collectd.localhost.table-' + app.id + '-memory.gauge-rss, "' + timeBucketSize + 'min", "avg")';
|
||||
|
||||
Client.graphs([target], '-' + timePeriod + 'min', {}, function (error, result) {
|
||||
if (error) return $scope.setError('memory', error);
|
||||
|
||||
// translate the data from bytes to MB
|
||||
var datapoints = result[0].datapoints.map(function (d) { return parseInt((d[0] / 1024 / 1024).toFixed(2)); });
|
||||
var labels = datapoints.map(function (d, index) {
|
||||
var dateTime = new Date(Date.now() - ((timePeriod - (index * timeBucketSize)) * 60 *1000));
|
||||
return ('0' + dateTime.getHours()).slice(-2) + ':00';
|
||||
});
|
||||
|
||||
var data = {
|
||||
labels: labels,
|
||||
datasets: [{
|
||||
label: 'Memory',
|
||||
backgroundColor: color || '#82C4F8',
|
||||
borderColor: color || '#2196F3',
|
||||
borderWidth: 2,
|
||||
pointBackgroundColor: color || 'rgba(151,187,205,1)',
|
||||
pointBorderColor: color || '#2196F3',
|
||||
pointHoverBackgroundColor: color || '#82C4F8',
|
||||
pointHoverBorderColor: color || '#82C4F8',
|
||||
data: datapoints
|
||||
}]
|
||||
};
|
||||
|
||||
var scaleMax = 0;
|
||||
if ($scope.activeApp === 'system') {
|
||||
scaleMax = $scope.memory.memory + $scope.memory.swap;
|
||||
} else {
|
||||
scaleMax = $scope.activeApp.memoryLimit || $scope.activeApp.manifest.memoryLimit || (256 * 1024 * 1024);
|
||||
}
|
||||
|
||||
var stepSize;
|
||||
if (scaleMax >= (8 * 1024 * 1024 * 1024)) stepSize = 1024;
|
||||
else if (scaleMax >= (4 * 1024 * 1024 * 1024)) stepSize = 512;
|
||||
else if (scaleMax >= (2 * 1024 * 1024 * 1024)) stepSize = 256;
|
||||
else stepSize = 128;
|
||||
|
||||
var options = {
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
scales: {
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
min: 0,
|
||||
max: Math.round(scaleMax / (1024 * 1024)),
|
||||
stepSize: stepSize,
|
||||
beginAtZero: true
|
||||
}
|
||||
}]
|
||||
}
|
||||
};
|
||||
|
||||
var ctx = $('#memoryAppChart').get(0).getContext('2d');
|
||||
new Chart(ctx, { type: 'line', data: data, options: options });
|
||||
});
|
||||
};
|
||||
|
||||
$scope.updateMemorySystemChart = function () {
|
||||
var targets = [];
|
||||
var targetsInfo = [];
|
||||
|
||||
targets.push('summarize(collectd.localhost.memory.memory-used, "1min", "avg")');
|
||||
targetsInfo.push({ label: 'Memory (RAM)', color: '#2196F3' });
|
||||
|
||||
targets.push('summarize(collectd.localhost.swap.swap-used, "1min", "avg")');
|
||||
targetsInfo.push({ label: 'Swap', color: '#2196A9' });
|
||||
|
||||
targets.push('summarize(sum(collectd.localhost.memory.memory-buffered, collectd.localhost.memory.memory-cached), "1min", "avg")');
|
||||
targetsInfo.push({ label: 'Memory (Cached)', color: '#f0ad4e' });
|
||||
|
||||
targets.push('summarize(collectd.localhost.swap.swap-cached, "1min", "avg")');
|
||||
targetsInfo.push({ label: 'Swap (Cached)', color: '#f0cd4e' });
|
||||
|
||||
targets.push('summarize(collectd.localhost.memory.memory-free, "1min", "avg")');
|
||||
targetsInfo.push({ label: 'Memory (Free)', color: '#27DD65' });
|
||||
|
||||
targets.push('summarize(collectd.localhost.swap.swap-free, "1min", "avg")');
|
||||
targetsInfo.push({ label: 'Swap (Free)', color: '#27CE65' });
|
||||
|
||||
Client.graphs(targets, '-1min', {}, function (error, result) {
|
||||
if (error) return $scope.setError('memory', error);
|
||||
|
||||
$scope.memoryUsageSystem = result.map(function (data, index) {
|
||||
return {
|
||||
value: bytesToMegaBytes(data.datapoints[0][0]),
|
||||
color: targetsInfo[index].color,
|
||||
highlight: targetsInfo[index].color,
|
||||
label: targetsInfo[index].label
|
||||
};
|
||||
});
|
||||
|
||||
var tmp = {
|
||||
datasets: [{
|
||||
data: result.map(function (data) { return bytesToMegaBytes(data.datapoints[0][0]); }),
|
||||
backgroundColor: result.map(function (data, index) { return targetsInfo[index].color; })
|
||||
}],
|
||||
labels: result.map(function (data, index) { return targetsInfo[index].label; })
|
||||
};
|
||||
|
||||
var options = {
|
||||
onClick: function (/*event, dataset*/) {
|
||||
$scope.setMemoryApp('system');
|
||||
},
|
||||
legend: { display: false }
|
||||
};
|
||||
|
||||
var ctx = $('#memoryUsageSystemChart').get(0).getContext('2d');
|
||||
new Chart(ctx, { type: 'doughnut', data: tmp, options: options });
|
||||
});
|
||||
};
|
||||
|
||||
$scope.updateMemoryAppsChart = function () {
|
||||
var targets = [];
|
||||
var targetsInfo = [];
|
||||
|
||||
colorIndex = 0;
|
||||
$scope.installedApps.forEach(function (app) {
|
||||
targets.push('summarize(collectd.localhost.table-' + app.id + '-memory.gauge-rss, "1min", "avg")');
|
||||
targetsInfo.push({
|
||||
label: app.fqdn,
|
||||
color: getNextColor(),
|
||||
app: app
|
||||
});
|
||||
});
|
||||
|
||||
// we split up the request, to avoid too large query strings into graphite
|
||||
var tmp = [];
|
||||
var aggregatedResult= [];
|
||||
|
||||
while (targets.length > 0) tmp.push(targets.splice(0, 10));
|
||||
|
||||
asyncForEach(tmp, function (targets, callback) {
|
||||
Client.graphs(targets, '-1min', {}, function (error, result) {
|
||||
if (error) return callback(error);
|
||||
|
||||
aggregatedResult = aggregatedResult.concat(result);
|
||||
|
||||
callback(null);
|
||||
});
|
||||
}, function (error) {
|
||||
if (error) return $scope.setError('memory', error);
|
||||
|
||||
$scope.memoryUsageApps = aggregatedResult.map(function (data, index) {
|
||||
return {
|
||||
value: bytesToMegaBytes(data.datapoints[0][0]),
|
||||
color: targetsInfo[index].color,
|
||||
highlight: targetsInfo[index].color,
|
||||
label: targetsInfo[index].label
|
||||
};
|
||||
});
|
||||
|
||||
var tmp = {
|
||||
datasets: [{
|
||||
data: aggregatedResult.map(function (data) { return bytesToMegaBytes(data.datapoints[0][0]); }),
|
||||
backgroundColor: aggregatedResult.map(function (data, index) { return targetsInfo[index].color; })
|
||||
}],
|
||||
labels: aggregatedResult.map(function (data, index) { return targetsInfo[index].label; })
|
||||
};
|
||||
|
||||
var options = {
|
||||
onClick: function (event, dataset) {
|
||||
var selectedDataInfo = targetsInfo.find(function (info) { return info.label === dataset[0]._model.label; });
|
||||
if (selectedDataInfo) $scope.setMemoryApp(selectedDataInfo.app, selectedDataInfo.color);
|
||||
},
|
||||
legend: { display: false }
|
||||
};
|
||||
|
||||
var ctx = $('#memoryUsageAppsChart').get(0).getContext('2d');
|
||||
new Chart(ctx, { type: 'doughnut', data: tmp, options: options });
|
||||
});
|
||||
};
|
||||
|
||||
function getMemory(callback) {
|
||||
Client.memory(function (error, memory) {
|
||||
if (error) console.error(error);
|
||||
|
||||
$scope.memory = memory;
|
||||
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
Client.onReady(function () {
|
||||
getMemory(function () {
|
||||
$scope.updateMemorySystemChart();
|
||||
$scope.updateMemoryAppsChart();
|
||||
$scope.setMemoryApp('system');
|
||||
});
|
||||
});
|
||||
|
||||
$('.modal-backdrop').remove();
|
||||
}]);
|
||||
Reference in New Issue
Block a user