diff --git a/app/app.js b/app/app.js
index d9a48daf6..7a4a4dbcc 100644
--- a/app/app.js
+++ b/app/app.js
@@ -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'
diff --git a/app/components/container/container.html b/app/components/container/container.html
index 8843449c2..9f45e92fc 100644
--- a/app/components/container/container.html
+++ b/app/components/container/container.html
@@ -133,6 +133,10 @@
Logs: |
stdout/stderr |
+
+ Stats: |
+ stats |
+
Top: |
Top |
diff --git a/app/components/stats/stats.html b/app/components/stats/stats.html
new file mode 100644
index 000000000..365a931db
--- /dev/null
+++ b/app/components/stats/stats.html
@@ -0,0 +1,21 @@
+
+
+
Stats
+
+
+
+
+
+ Time read |
+ CPU usage |
+ Stat |
+
+
+ |
+ |
+ |
+
+
+
+
+
diff --git a/app/components/stats/statsController.js b/app/components/stats/statsController.js
new file mode 100644
index 000000000..4f620c33b
--- /dev/null
+++ b/app/components/stats/statsController.js
@@ -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)
+ //});
+ }
+ }]);
\ No newline at end of file
diff --git a/app/shared/services.js b/app/shared/services.js
index a996e20cf..41c809342 100644
--- a/app/shared/services.js
+++ b/app/shared/services.js
@@ -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"));
diff --git a/test/unit/app/components/statsController.spec.js b/test/unit/app/components/statsController.spec.js
new file mode 100644
index 000000000..c26aa06c3
--- /dev/null
+++ b/test/unit/app/components/statsController.spec.js
@@ -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();
+ });
+});
\ No newline at end of file