mirror of https://github.com/portainer/portainer
				
				
				
			Added remaining memory stats, change humansize filter to give more accurate sizes.
							parent
							
								
									b99fe5bf55
								
							
						
					
					
						commit
						5a51495432
					
				| 
						 | 
				
			
			@ -1,24 +1,41 @@
 | 
			
		|||
<div class="row">
 | 
			
		||||
    <div class="col-xs-12">
 | 
			
		||||
        <h1>Stats</h1>
 | 
			
		||||
 | 
			
		||||
        <h2>CPU Usage</h2>
 | 
			
		||||
 | 
			
		||||
        <div class="row">
 | 
			
		||||
            <div class="col-sm-8">
 | 
			
		||||
                <canvas id="cpu-stats-chart" width="700" height="300"></canvas>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="col-sm-4">
 | 
			
		||||
                <h3>Other CPU usage data</h3>
 | 
			
		||||
                <p>TODO</p>
 | 
			
		||||
            <div class="col-sm-7">
 | 
			
		||||
                <canvas id="cpu-stats-chart" width="650" height="300"></canvas>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <h2>Memory</h2>
 | 
			
		||||
 | 
			
		||||
        <div class="row">
 | 
			
		||||
            <div class="col-sm-8">
 | 
			
		||||
                <canvas id="memory-stats-chart" width="700" height="300"></canvas>
 | 
			
		||||
            <div class="col-sm-7">
 | 
			
		||||
                <canvas id="memory-stats-chart" width="650" height="300"></canvas>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="col-sm-4">
 | 
			
		||||
                <h3>Other Memory Stats</h3>
 | 
			
		||||
                <p>TODO</p>
 | 
			
		||||
            <div class="col-sm-offset-1 col-sm-4">
 | 
			
		||||
                <table class="table">
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <td>Max usage</td>
 | 
			
		||||
                        <td>{{ data.memory_stats.max_usage | humansize }}</td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <td>Limit</td>
 | 
			
		||||
                        <td>{{ data.memory_stats.limit | humansize }}</td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                </table>
 | 
			
		||||
                <accordion>
 | 
			
		||||
                    <accordion-group heading="Other stats">
 | 
			
		||||
                        <table class="table">
 | 
			
		||||
                            <tr ng-repeat="(key, value) in data.memory_stats.stats">
 | 
			
		||||
                                <td>{{ key }}</td>
 | 
			
		||||
                                <td>{{ value }}</td>
 | 
			
		||||
                            </tr>
 | 
			
		||||
                        </table>
 | 
			
		||||
                    </accordion-group>
 | 
			
		||||
                </accordion>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,9 +56,9 @@ angular.module('stats', [])
 | 
			
		|||
            },
 | 
			
		||||
            {
 | 
			
		||||
                scaleLabel: function (valueObj) {
 | 
			
		||||
                    return humansizeFilter(parseInt(valueObj.value));
 | 
			
		||||
                    return humansizeFilter(parseInt(valueObj.value, 10));
 | 
			
		||||
                },
 | 
			
		||||
                responsive: true,
 | 
			
		||||
                responsive: true
 | 
			
		||||
                //scaleOverride: true,
 | 
			
		||||
                //scaleSteps: 10,
 | 
			
		||||
                //scaleStepWidth: Math.ceil(initialStats.memory_stats.limit / 10),
 | 
			
		||||
| 
						 | 
				
			
			@ -77,14 +77,20 @@ angular.module('stats', [])
 | 
			
		|||
                }
 | 
			
		||||
 | 
			
		||||
                // Update graph with latest data
 | 
			
		||||
                $scope.data = d;
 | 
			
		||||
                updateChart(d);
 | 
			
		||||
                updateMemoryChart(d);
 | 
			
		||||
                $timeout(updateStats, 1000); // TODO: Switch to setInterval for more consistent readings
 | 
			
		||||
                timeout = $timeout(updateStats, 1000);
 | 
			
		||||
            }, function () {
 | 
			
		||||
                Messages.error('Unable to retrieve stats', 'Is this container running?');
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var timeout;
 | 
			
		||||
        $scope.$on('$destroy', function () {
 | 
			
		||||
            $timeout.cancel(timeout);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        updateStats();
 | 
			
		||||
 | 
			
		||||
        function updateChart(data) {
 | 
			
		||||
| 
						 | 
				
			
			@ -116,8 +122,7 @@ angular.module('stats', [])
 | 
			
		|||
                //console.log('size thing:', curCpu.cpu_usage.percpu_usage);
 | 
			
		||||
                cpuPercent = (cpuDelta / systemDelta) * curCpu.cpu_usage.percpu_usage.length * 100.0;
 | 
			
		||||
            }
 | 
			
		||||
            return Math.random() * 100;
 | 
			
		||||
            //return cpuPercent; TODO: Switch back to the real value
 | 
			
		||||
            return cpuPercent;
 | 
			
		||||
        }
 | 
			
		||||
    }])
 | 
			
		||||
;
 | 
			
		||||
| 
						 | 
				
			
			@ -71,7 +71,9 @@ angular.module('dockerui.filters', [])
 | 
			
		|||
                return 'n/a';
 | 
			
		||||
            }
 | 
			
		||||
            var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)), 10);
 | 
			
		||||
            return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[[i]];
 | 
			
		||||
            var value = bytes / Math.pow(1024, i);
 | 
			
		||||
            var decimalPlaces = (i < 1) ? 0 : (i - 1);
 | 
			
		||||
            return value.toFixed(decimalPlaces) + ' ' + sizes[[i]];
 | 
			
		||||
        };
 | 
			
		||||
    })
 | 
			
		||||
    .filter('containername', function () {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,18 +14,18 @@ describe("StatsController", function () {
 | 
			
		|||
        });
 | 
			
		||||
    }));
 | 
			
		||||
 | 
			
		||||
    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();
 | 
			
		||||
    });
 | 
			
		||||
    //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();
 | 
			
		||||
    //});
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			@ -106,19 +106,19 @@ describe('filters', function () {
 | 
			
		|||
        }));
 | 
			
		||||
 | 
			
		||||
        it('should handle KB values', inject(function (humansizeFilter) {
 | 
			
		||||
            expect(humansizeFilter(5120)).toBe('5 KB');
 | 
			
		||||
            expect(humansizeFilter(5 * 1024)).toBe('5 KB');
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        it('should handle MB values', inject(function (humansizeFilter) {
 | 
			
		||||
            expect(humansizeFilter(5 * Math.pow(10, 6))).toBe('5 MB');
 | 
			
		||||
            expect(humansizeFilter(5 * 1024 * 1024)).toBe('5.0 MB');
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        it('should handle GB values', inject(function (humansizeFilter) {
 | 
			
		||||
            expect(humansizeFilter(5 * Math.pow(10, 9))).toBe('5 GB');
 | 
			
		||||
            expect(humansizeFilter(5 * 1024 * 1024 * 1024)).toBe('5.00 GB');
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        it('should handle TB values', inject(function (humansizeFilter) {
 | 
			
		||||
            expect(humansizeFilter(5 * Math.pow(10, 12))).toBe('5 TB');
 | 
			
		||||
            expect(humansizeFilter(5 * 1024 * 1024 * 1024 * 1024)).toBe('5.000 TB');
 | 
			
		||||
        }));
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue