mirror of
https://github.com/portainer/portainer.git
synced 2025-07-25 08:19:40 +02:00
Implemented CPU usage graph, upgraded to Chart.js 1.0.2, broke dashboard charts, tests.
This commit is contained in:
parent
6cb658a1ef
commit
d243a83c5c
5 changed files with 53 additions and 80 deletions
|
@ -1,21 +1,9 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
<h2>Stats</h2>
|
<h1>Stats</h1>
|
||||||
<canvas id="cpu-stats-chart" width="700"></canvas>
|
<h2>CPU Usage</h2>
|
||||||
<br>
|
<canvas id="cpu-stats-chart" width="700" height="300"></canvas>
|
||||||
<table class="table">
|
<canvas id="memory-stats-chart" width="700" height="300"></canvas>
|
||||||
<tbody>
|
<h2>Memory</h2>
|
||||||
<tr>
|
|
||||||
<th>Time read</th>
|
|
||||||
<th>CPU usage</th>
|
|
||||||
<th>Stat</th>
|
|
||||||
</tr>
|
|
||||||
<tr ng-repeat="stat in dockerStats">
|
|
||||||
<td ng-bind="stat.read"/>
|
|
||||||
<td ng-bind="calculateCPUPercent(stat)"/>
|
|
||||||
<td ng-bind="stat"/>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,36 +1,53 @@
|
||||||
angular.module('stats', [])
|
angular.module('stats', [])
|
||||||
.controller('StatsController', ['Settings', '$scope', 'Messages', '$timeout', 'Container', 'LineChart', '$routeParams', function (Settings, $scope, Messages, $timeout, Container, LineChart, $routeParams) {
|
.controller('StatsController', ['Settings', '$scope', 'Messages', '$timeout', 'Container', '$routeParams', function (Settings, $scope, Messages, $timeout, Container, $routeParams) {
|
||||||
var sessionKey = 'dockeruiStats-' + $routeParams.id;
|
// TODO: Implement memory chart, force scale to 0-100 for cpu, 0 to limit for memory, fix charts on dashboard
|
||||||
var localData = sessionStorage.getItem(sessionKey);
|
|
||||||
if (localData) {
|
var labels = [];
|
||||||
$scope.dockerStats = localData;
|
var data = [];
|
||||||
} else {
|
for (var i = 0; i < 40; i ++) {
|
||||||
$scope.dockerStats = [];
|
labels.push('');
|
||||||
|
data.push(0);
|
||||||
}
|
}
|
||||||
|
var dataset = { // CPU Usage
|
||||||
|
fillColor: "rgba(151,187,205,0.5)",
|
||||||
|
strokeColor: "rgba(151,187,205,1)",
|
||||||
|
pointColor: "rgba(151,187,205,1)",
|
||||||
|
pointStrokeColor: "#fff",
|
||||||
|
data: data
|
||||||
|
};
|
||||||
|
|
||||||
|
var chart = new Chart($('#cpu-stats-chart').get(0).getContext("2d")).Line({
|
||||||
|
labels: labels,
|
||||||
|
datasets: [dataset]
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
function updateStats() {
|
function updateStats() {
|
||||||
Container.stats({id: $routeParams.id}, function (d) {
|
Container.stats({id: $routeParams.id}, function (d) {
|
||||||
console.log(d);
|
|
||||||
var arr = Object.keys(d).map(function (key) {
|
var arr = Object.keys(d).map(function (key) {
|
||||||
return d[key];
|
return d[key];
|
||||||
});
|
});
|
||||||
if (arr.join('').indexOf('no such id') !== -1) {
|
if (arr.join('').indexOf('no such id') !== -1) {
|
||||||
Messages.error('Unable to retrieve container stats', 'Has this container been removed?');
|
Messages.error('Unable to retrieve stats', 'Is this container running?');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$scope.dockerStats.push(d);
|
|
||||||
sessionStorage.setItem(sessionKey, $scope.dockerStats);
|
|
||||||
$timeout(updateStats, 1000);
|
|
||||||
// Update graph with latest data
|
// Update graph with latest data
|
||||||
updateChart($scope.dockerStats);
|
updateChart(d);
|
||||||
|
$timeout(updateStats, 1000); // TODO: Switch to setInterval for more consistent readings
|
||||||
}, function () {
|
}, function () {
|
||||||
Messages.error('Unable to retrieve container stats', 'Has this container been removed?');
|
Messages.error('Unable to retrieve stats', 'Is this container running?');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateStats();
|
updateStats();
|
||||||
|
|
||||||
|
function updateChart(data) {
|
||||||
|
console.log('updateChart', data);
|
||||||
|
chart.addData([$scope.calculateCPUPercent(data)], new Date(data.read).toLocaleTimeString());
|
||||||
|
chart.removeData();
|
||||||
|
}
|
||||||
|
|
||||||
$scope.calculateCPUPercent = function (stats) {
|
$scope.calculateCPUPercent = function (stats) {
|
||||||
// Same algorithm the official client uses: https://github.com/docker/docker/blob/master/api/client/stats.go#L195-L208
|
// Same algorithm the official client uses: https://github.com/docker/docker/blob/master/api/client/stats.go#L195-L208
|
||||||
var prevCpu = stats.precpu_stats;
|
var prevCpu = stats.precpu_stats;
|
||||||
|
@ -44,15 +61,10 @@ angular.module('stats', [])
|
||||||
var systemDelta = curCpu.system_cpu_usage - prevCpu.system_cpu_usage;
|
var systemDelta = curCpu.system_cpu_usage - prevCpu.system_cpu_usage;
|
||||||
|
|
||||||
if (systemDelta > 0.0 && cpuDelta > 0.0) {
|
if (systemDelta > 0.0 && cpuDelta > 0.0) {
|
||||||
cpuPercent = (cpuDelta / systemDelta) * curCpu.cpu_usage.percpu_usage.size() * 100.0;
|
//console.log('size thing:', curCpu.cpu_usage.percpu_usage);
|
||||||
|
cpuPercent = (cpuDelta / systemDelta) * curCpu.cpu_usage.percpu_usage.length * 100.0;
|
||||||
}
|
}
|
||||||
return cpuPercent;
|
return Math.random() * 100;
|
||||||
|
//return cpuPercent; TODO: Switch back to the real value
|
||||||
};
|
};
|
||||||
|
|
||||||
function updateChart(data) {
|
|
||||||
// TODO: Build data in the right format and create chart.
|
|
||||||
//LineChart.build('#cpu-stats-chart', $scope.dockerStats, function (d) {
|
|
||||||
// return $scope.calculateCPUPercent(d)
|
|
||||||
//});
|
|
||||||
}
|
|
||||||
}]);
|
}]);
|
|
@ -18,7 +18,7 @@ angular.module('dockerui.services', ['ngResource'])
|
||||||
create: {method: 'POST', params: {action: 'create'}},
|
create: {method: 'POST', params: {action: 'create'}},
|
||||||
remove: {method: 'DELETE', params: {id: '@id', v: 0}},
|
remove: {method: 'DELETE', params: {id: '@id', v: 0}},
|
||||||
rename: {method: 'POST', params: {id: '@id', action: 'rename'}, isArray: false},
|
rename: {method: 'POST', params: {id: '@id', action: 'rename'}, isArray: false},
|
||||||
stats: {method: 'GET', params: {id: '@id', stream: false, action: 'stats'}}
|
stats: {method: 'GET', params: {id: '@id', stream: false, action: 'stats'}, timeout: 2000}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.factory('ContainerCommit', function ($resource, $http, Settings) {
|
.factory('ContainerCommit', function ($resource, $http, Settings) {
|
||||||
|
|
50
assets/js/Chart.min.js
vendored
50
assets/js/Chart.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -9,6 +9,7 @@ files = [
|
||||||
'assets/js/jquery.gritter.min.js',
|
'assets/js/jquery.gritter.min.js',
|
||||||
'assets/js/bootstrap.min.js',
|
'assets/js/bootstrap.min.js',
|
||||||
'assets/js/spin.js',
|
'assets/js/spin.js',
|
||||||
|
'assets/js/Chart.min.js',
|
||||||
'dist/angular.js',
|
'dist/angular.js',
|
||||||
'assets/js/ui-bootstrap/ui-bootstrap-custom-tpls-0.12.0.min.js',
|
'assets/js/ui-bootstrap/ui-bootstrap-custom-tpls-0.12.0.min.js',
|
||||||
'assets/js/angular-vis.js',
|
'assets/js/angular-vis.js',
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue