diff --git a/html/css/style.css b/html/css/style.css index 88249c1..0a42bd1 100644 --- a/html/css/style.css +++ b/html/css/style.css @@ -14,6 +14,7 @@ .chart { width: 100%; height: 500px; + display: none; } #container-stats { diff --git a/html/index.html b/html/index.html index f566ac6..875bf27 100644 --- a/html/index.html +++ b/html/index.html @@ -11,6 +11,12 @@
+
+ + + + +

Docker Container Stats @@ -60,21 +66,32 @@
-

Mem

-
-
-

Net In

-
-
-

Net Out

-
-
-

Block In

-
-
-

Block Out

-
+ +

Mem

+
+ +
+ +

Net In

+
+ +
+ +

Net Out

+
+ +
+ +

Block In

+
+ +
+ +

Block Out

+
+ +
diff --git a/html/js/script.js b/html/js/script.js index c64c469..1ce9438 100644 --- a/html/js/script.js +++ b/html/js/script.js @@ -1,5 +1,8 @@ 'use strict'; +var zoom = 'hour'; +var selectedContainerId = null; + var unitRound = function(i) { return parseFloat(Math.round(i * 100) / 100).toFixed(2); }; @@ -47,26 +50,60 @@ var renderLatestStats = function(containerId) { }; var renderChart = function(elementId, containerId, chart) { - $.get('/rs/container/'+containerId+'/'+chart, function(stats) { + var url; + if (containerId) { + url = '/rs/container/'+containerId+'/'+chart+'/'+zoom; + } else { + url = '/rs/all/'+chart+'/'+zoom; + } + $.get(url, function(stats) { + $('#'+elementId).show(); + $('#'+elementId+'-warn').hide(); + if (stats.length <= 1) { + $('#'+elementId).hide(); + $('#'+elementId+'-warn').show(); + return; + } var data = google.visualization.arrayToDataTable(stats); var options = { - legend: { position: 'bottom' } + legend: { position: 'right' } }; var chart = new google.visualization.LineChart(document.getElementById(elementId)); chart.draw(data, options); }); }; -var selectContainer = function(id, name) { - $('#selected-container').text('Selected container: ' + (name ? name : id) + ' (click to change)'); - $('#container-list-collapse').collapse('hide'); - $('#container-stats').show(); +var renderContainerStats = function(id) { renderLatestStats(id); renderChart('mem-chart', id, 'mem'); renderChart('net-in-chart', id, 'net_in'); renderChart('net-out-chart', id, 'net_out'); renderChart('block-in-chart', id, 'block_in'); - renderChart('block-out-chart', id, 'block_in'); + renderChart('block-out-chart', id, 'block_out'); +}; + +var selectContainer = function(id, name) { + $('#selected-container').text('Selected container: ' + (name ? name : id) + ' (click to change)'); + $('#container-list-collapse').collapse('hide'); + $('#container-stats').show(); + renderContainerStats(id); + selectedContainerId = id; +}; + +var renderAllContainerStats = function() { + renderChart('mem-chart', null, 'mem'); + renderChart('net-in-chart', null, 'net_in'); + renderChart('net-out-chart', null, 'net_out'); + renderChart('block-in-chart', null, 'block_in'); + renderChart('block-out-chart', null, 'block_out'); +}; + +var reRenderCharts = function() { + if (selectedContainerId) { + renderContainerStats(selectedContainerId); + } else { + renderAllContainerStats(); + } }; var addItemToContainerList = function(list, container) { @@ -98,10 +135,25 @@ var loadContainerList = function() { }); }; +var onZoomButtonClick = function(level) { + zoom = level; + $('#zoom-buttons > button').removeClass('btn-primary'); + $('#zoom-'+level).addClass('btn-primary'); + reRenderCharts(); +}; + +var initZoomButton = function() { + $('#zoom-hour').click(function() { onZoomButtonClick('hour'); }); + $('#zoom-day').click(function() { onZoomButtonClick('day'); }); + $('#zoom-week').click(function() { onZoomButtonClick('week'); }); + $('#zoom-month').click(function() { onZoomButtonClick('month'); }); +}; + var init = function() { google.charts.load('current', {packages: ['corechart']}); + initZoomButton(); loadContainerList(); - //google.charts.setOnLoadCallback(drawChart + renderAllContainerStats(); }; $(document).ready(init); diff --git a/httpd.js b/httpd.js index 749a497..0741f27 100644 --- a/httpd.js +++ b/httpd.js @@ -9,6 +9,57 @@ var express = require("express"); var app = express(); var db = new sqlite3.Database(DB_FILE); +var isValidChart = function(s) { + return /^(net_in|net_out|block_in|block_out|mem)$/.test(s); +}; + +var isValidZoom = function(s) { + return /^(hour|day|week|month)$/.test(s); +}; + +var getMinDate = function(zoom) { + var now = moment(); + now.subtract(1, zoom + 's'); + return now.format('YYYY-MM-DD HH:mm:ss'); +}; + +var processPreResult = function(result, containers, preResult) { + var timestamps = []; + for (var ts in preResult) { + timestamps.push(ts); + } + timestamps.sort(); + for (var k=0; k= ? ORDER BY ts ASC", id, minDate, function(err, rows) { + var prev = 0; + for (var i=0; i= ? ORDER BY ts ASC", req.params.id, minDate, function(err, rows) { var json = [['Time', 'Bytes']]; var prev = 0; for (var i=0; i