mirror of https://github.com/portainer/portainer
Current progress on stats page, nonfunctional.
parent
66894e7596
commit
b7daf91723
|
@ -1,4 +1,4 @@
|
|||
angular.module('dockerui', ['dockerui.templates', 'ngRoute', 'dockerui.services', 'dockerui.filters', 'masthead', 'footer', 'dashboard', 'container', 'containers', 'containersNetwork', 'images', 'image', 'pullImage', 'startContainer', 'sidebar', 'info', 'builder', 'containerLogs', 'containerTop', 'events'])
|
||||
angular.module('dockerui', ['dockerui.templates', 'ngRoute', 'dockerui.services', 'dockerui.filters', 'masthead', 'footer', 'dashboard', 'container', 'containers', 'containersNetwork', 'images', 'image', 'pullImage', 'startContainer', 'sidebar', 'info', 'builder', 'containerLogs', 'containerTop', 'events', 'stats'])
|
||||
.config(['$routeProvider', function ($routeProvider) {
|
||||
'use strict';
|
||||
$routeProvider.when('/', {
|
||||
|
@ -21,6 +21,10 @@ angular.module('dockerui', ['dockerui.templates', 'ngRoute', 'dockerui.services'
|
|||
templateUrl: 'app/components/containerTop/containerTop.html',
|
||||
controller: 'ContainerTopController'
|
||||
});
|
||||
$routeProvider.when('/containers/:id/stats', {
|
||||
templateUrl: 'app/components/stats/stats.html',
|
||||
controller: 'StatsController'
|
||||
});
|
||||
$routeProvider.when('/containers_network', {
|
||||
templateUrl: 'app/components/containersNetwork/containersNetwork.html',
|
||||
controller: 'ContainersNetworkController'
|
||||
|
|
|
@ -133,6 +133,10 @@
|
|||
<td>Logs:</td>
|
||||
<td><a href="#/containers/{{ container.Id }}/logs">stdout/stderr</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Stats:</td>
|
||||
<td><a href="#/containers/{{ container.Id }}/stats">stats</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Top:</td>
|
||||
<td><a href="#/containers/{{ container.Id }}/top">Top</a></td>
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<h2>Stats</h2>
|
||||
<canvas id="cpu-stats-chart" width="700"></canvas>
|
||||
<br>
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<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>
|
|
@ -0,0 +1,56 @@
|
|||
angular.module('stats', [])
|
||||
.controller('StatsController', ['Settings', '$scope', 'Messages', '$timeout', 'Container', 'LineChart', '$routeParams', function (Settings, $scope, Messages, $timeout, Container, LineChart, $routeParams) {
|
||||
var sessionKey = 'dockeruiStats-' + $routeParams.id;
|
||||
var localData = sessionStorage.getItem(sessionKey);
|
||||
if (localData) {
|
||||
$scope.dockerStats = localData;
|
||||
} else {
|
||||
$scope.dockerStats = [];
|
||||
}
|
||||
|
||||
|
||||
function updateStats() {
|
||||
Container.stats({id: $routeParams.id}, function (d) {
|
||||
console.log(d);
|
||||
var arr = Object.keys(d).map(function (key) {return d[key];});
|
||||
if (arr.join('').indexOf('no such id') !== -1) {
|
||||
Messages.error('Unable to retrieve container stats', 'Has this container been removed?');
|
||||
return;
|
||||
}
|
||||
$scope.dockerStats.push(d);
|
||||
sessionStorage.setItem(sessionKey, $scope.dockerStats);
|
||||
$timeout(updateStats, 1000);
|
||||
// Update graph with latest data
|
||||
updateChart($scope.dockerStats);
|
||||
}, function () {
|
||||
Messages.error('Unable to retrieve container stats', 'Has this container been removed?');
|
||||
});
|
||||
}
|
||||
|
||||
updateStats();
|
||||
|
||||
$scope.calculateCPUPercent = function (stats) {
|
||||
// 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 curCpu = stats.cpu_stats;
|
||||
|
||||
var cpuPercent = 0.0;
|
||||
|
||||
// calculate the change for the cpu usage of the container in between readings
|
||||
var cpuDelta = curCpu.cpu_usage.total_usage - prevCpu.cpu_usage.total_usage;
|
||||
// calculate the change for the entire system between readings
|
||||
var systemDelta = curCpu.system_cpu_usage - prevCpu.system_cpu_usage;
|
||||
|
||||
if (systemDelta > 0.0 && cpuDelta > 0.0) {
|
||||
cpuPercent = (cpuDelta / systemDelta) * curCpu.cpu_usage.percpu_usage.size() * 100.0;
|
||||
}
|
||||
return cpuPercent
|
||||
};
|
||||
|
||||
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)
|
||||
//});
|
||||
}
|
||||
}]);
|
|
@ -17,7 +17,8 @@ angular.module('dockerui.services', ['ngResource'])
|
|||
changes: {method: 'GET', params: {action: 'changes'}, isArray: true},
|
||||
create: {method: 'POST', params: {action: 'create'}},
|
||||
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'}}
|
||||
});
|
||||
})
|
||||
.factory('ContainerCommit', function ($resource, $http, Settings) {
|
||||
|
@ -192,7 +193,6 @@ angular.module('dockerui.services', ['ngResource'])
|
|||
})
|
||||
.factory('LineChart', function (Settings) {
|
||||
'use strict';
|
||||
var url = Settings.rawUrl + '/build';
|
||||
return {
|
||||
build: function (id, data, getkey) {
|
||||
var chart = new Chart($(id).get(0).getContext("2d"));
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
describe("StatsController", function () {
|
||||
var $scope, $httpBackend, $routeParams;
|
||||
|
||||
beforeEach(angular.mock.module('dockerui'));
|
||||
|
||||
beforeEach(inject(function (_$rootScope_, _$httpBackend_, $controller, _$routeParams_) {
|
||||
$scope = _$rootScope_.$new();
|
||||
$httpBackend = _$httpBackend_;
|
||||
$routeParams = _$routeParams_;
|
||||
$routeParams.id = 'b17882378cee8ec0136f482681b764cca430befd52a9bfd1bde031f49b8bba9f';
|
||||
$controller('StatsController', {
|
||||
'$scope': $scope,
|
||||
'$routeParams': $routeParams
|
||||
});
|
||||
}));
|
||||
|
||||
it("should test controller initialize", function () {
|
||||
$httpBackend.expectGET('dockerapi/containers/b17882378cee8ec0136f482681b764cca430befd52a9bfd1bde031f49b8bba9f/stats?stream=false').respond(200);
|
||||
//expect($scope.ps_args).toBeDefined();
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it("a correct top request to the Docker remote API", function () {
|
||||
//$httpBackend.expectGET('dockerapi/containers/' + $routeParams.id + '/top?ps_args=').respond(200);
|
||||
//$routeParams.id = '123456789123456789123456789';
|
||||
//$scope.ps_args = 'aux';
|
||||
//$httpBackend.expectGET('dockerapi/containers/' + $routeParams.id + '/top?ps_args=' + $scope.ps_args).respond(200);
|
||||
//$scope.getTop();
|
||||
//$httpBackend.flush();
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue