Current progress on stats page, nonfunctional.

pull/2/head
Kevan Ahlquist 2015-08-25 00:55:54 -05:00
parent 66894e7596
commit b7daf91723
6 changed files with 119 additions and 3 deletions

View File

@ -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'

View File

@ -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>

View File

@ -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>

View File

@ -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)
//});
}
}]);

View File

@ -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"));

View File

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