From ce5786857ddd158765f9c117a14c108128fa140b Mon Sep 17 00:00:00 2001 From: Rafal Wilinski Date: Mon, 12 Sep 2016 17:40:53 +0200 Subject: [PATCH 01/14] Introduce StatusCodes chart --- app.js | 46 ++++++++++++++++++++++++++++++++++++++++++---- index.html | 8 ++++++++ 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/app.js b/app.js index f2f1217..1f891b6 100644 --- a/app.js +++ b/app.js @@ -10,6 +10,7 @@ Chart.defaults.global.elements.line.borderWidth = 2; var socket = io(location.protocol + '//' + location.hostname + ':' + location.port); var defaultSpan = 0; var spans = []; +var statusCodesColors = ['#75D701', '#47b8e0', '#ffc952', '#E53A40']; var defaultDataset = { label: '', @@ -43,12 +44,13 @@ var defaultOptions = { animation: false }; -var createChart = function (ctx, dataset) { +var createChart = function (ctx, dataset, color) { return new Chart(ctx, { type: 'line', data: { labels: [], - datasets: dataset + datasets: dataset, + color: color ? color : 'black', }, options: defaultOptions }); @@ -63,6 +65,7 @@ var memDataset = [Object.create(defaultDataset)]; var loadDataset = [Object.create(defaultDataset)]; var responseTimeDataset = [Object.create(defaultDataset)]; var rpsDataset = [Object.create(defaultDataset)]; +var statusCodesDataset = [Object.create(defaultDataset)]; var cpuStat = document.getElementById('cpuStat'); var memStat = document.getElementById('memStat'); @@ -75,14 +78,32 @@ var memChartCtx = document.getElementById("memChart"); var loadChartCtx = document.getElementById("loadChart"); var responseTimeChartCtx = document.getElementById("responseTimeChart"); var rpsChartCtx = document.getElementById("rpsChart"); +var statusCodesChartCtx = document.getElementById("statusCodesChart"); var cpuChart = createChart(cpuChartCtx, cpuDataset); var memChart = createChart(memChartCtx, memDataset); var loadChart = createChart(loadChartCtx, loadDataset); var responseTimeChart = createChart(responseTimeChartCtx, responseTimeDataset); var rpsChart = createChart(rpsChartCtx, rpsDataset); +var statusCodesChart = new Chart(statusCodesChartCtx, { + type: 'line', + data: { + labels: [], + datasets: [ + Object.create(defaultDataset), + Object.create(defaultDataset), + Object.create(defaultDataset), + Object.create(defaultDataset) + ] + }, + options: defaultOptions +}); -var charts = [cpuChart, memChart, loadChart, responseTimeChart, rpsChart]; +statusCodesChart.data.datasets.forEach((dataset, index) => { + dataset.borderColor = statusCodesColors[index]; +}); + +var charts = [cpuChart, memChart, loadChart, responseTimeChart, rpsChart, statusCodesChart]; var onSpanChange = function (e) { e.target.classList.add('active'); @@ -126,6 +147,13 @@ socket.on('start', function (data) { }); responseTimeChart.data.labels = data[defaultSpan].responses.map(addTimestamp); + for(var i = 0; i < 3; i++) { + statusCodesChart.data.datasets[i].data = data[defaultSpan].responses.map(function (point) { + return point[i+2]; + }); + } + statusCodesChart.data.labels = data[defaultSpan].responses.map(addTimestamp); + if (data[defaultSpan].responses.length >= 2) { var deltaTime = data[defaultSpan].responses[data[defaultSpan].responses.length - 1].timestamp - data[defaultSpan].responses[data[defaultSpan].responses.length - 2].timestamp; rpsStat.textContent = (data[defaultSpan].responses[data[defaultSpan].responses.length - 1].count / deltaTime * 1000).toFixed(2); @@ -177,13 +205,23 @@ socket.on('stats', function (data) { responseTimeChart.data.labels.push(data.responses.timestamp); var deltaTime = data.responses.timestamp - rpsChart.data.labels[rpsChart.data.labels.length - 1]; + if (deltaTime < 1) deltaTime = 1000; rpsStat.textContent = (data.responses.count / deltaTime * 1000).toFixed(2); rpsChart.data.datasets[0].data.push(data.responses.count / deltaTime * 1000); rpsChart.data.labels.push(data.responses.timestamp); + for(var i = 0; i < 3; i++) { + statusCodesChart.data.datasets[i].data.push(data.responses[i+2]); + } + statusCodesChart.data.labels.push(data.responses.timestamp); + charts.forEach(function (chart) { if (spans[defaultSpan].retention < chart.data.labels.length) { - chart.data.datasets[0].data.shift(); + + chart.data.datasets.forEach((dataset) => { + dataset.data.shift(); + }); + chart.data.labels.shift(); } diff --git a/index.html b/index.html index 783de47..be2af37 100644 --- a/index.html +++ b/index.html @@ -60,6 +60,14 @@

-

+
+
+
Status Codes
+
+
+ +
+
From e8fec6f1e0446d0d3c4192f9d7ee76988f92f4a8 Mon Sep 17 00:00:00 2001 From: Rafal Wilinski Date: Mon, 12 Sep 2016 17:41:18 +0200 Subject: [PATCH 02/14] Extend example - add route returning desired status code --- examples/index.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/examples/index.js b/examples/index.js index 42f9997..8dc3c41 100644 --- a/examples/index.js +++ b/examples/index.js @@ -1,12 +1,15 @@ /* eslint no-console: "off" */ const express = require('express'); - const app = express(); +const port = process.env.PORT || 3000; app.use(require('../index')({ path: '/' })); app.use(require('express-favicon-short-circuit')); -app.listen(3000, () => { - console.log('listening on http://0.0.0.0:3000'); +// Example route throwing requested status code +app.get('/return-status/:statusCode', (req, res) => res.sendStatus(req.params.statusCode)); + +app.listen(port, () => { + console.log(`Listening on http://0.0.0.0:${port}`); }); From 4c28e23194323819d65e39502662fab9c216573a Mon Sep 17 00:00:00 2001 From: Rafal Wilinski Date: Mon, 12 Sep 2016 17:41:44 +0200 Subject: [PATCH 03/14] Add benchmark tool to make random requests --- examples/package.json | 6 ++++-- examples/tester.js | 11 +++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 examples/tester.js diff --git a/examples/package.json b/examples/package.json index 4143826..8863bba 100644 --- a/examples/package.json +++ b/examples/package.json @@ -14,10 +14,12 @@ "license": "MIT", "dependencies": { "express": "^4.14.0", - "express-favicon-short-circuit": "^1.1.0" + "express-favicon-short-circuit": "^1.1.0", + "request": "^2.74.0" }, "scripts": { - "start": "node index.js" + "start": "node index.js", + "benchmark": "node tester.js" }, "repository": { "type": "git", diff --git a/examples/tester.js b/examples/tester.js new file mode 100644 index 0000000..fbd6337 --- /dev/null +++ b/examples/tester.js @@ -0,0 +1,11 @@ +const request = require('request'); +const requestUrl = 'http://localhost:3000/return-status/'; +const interval = 50; + +const makeDummyCall = () => setTimeout(() => { + const code = 200 + Math.random() * 399; + request.get(`${requestUrl}${code}`); + makeDummyCall(); +}, interval); + +makeDummyCall(); \ No newline at end of file From 8e2b695cd5c800fe3d0de18a40a9c0c11ea69318 Mon Sep 17 00:00:00 2001 From: Rafal Wilinski Date: Mon, 12 Sep 2016 17:58:24 +0200 Subject: [PATCH 04/14] Add visual identification --- src/public/index.html | 4 ++++ src/public/javascripts/app.js | 2 -- src/public/stylesheets/style.css | 6 +++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/public/index.html b/src/public/index.html index be2af37..2b2879e 100644 --- a/src/public/index.html +++ b/src/public/index.html @@ -63,6 +63,10 @@

-

Status Codes
+
2xx
+
3xx
+
4xx
+
5xx
diff --git a/src/public/javascripts/app.js b/src/public/javascripts/app.js index cb066a7..f03fb89 100644 --- a/src/public/javascripts/app.js +++ b/src/public/javascripts/app.js @@ -211,8 +211,6 @@ socket.on('stats', function (data) { var os = data.os; var responses = data.responses; - console.log(responses); - cpuStat.textContent = '0.0%'; if (os) { cpuStat.textContent = os.cpu.toFixed(1) + '%'; diff --git a/src/public/stylesheets/style.css b/src/public/stylesheets/style.css index 8c80bb3..d332dac 100644 --- a/src/public/stylesheets/style.css +++ b/src/public/stylesheets/style.css @@ -13,6 +13,10 @@ h5 { color: #888888; } +h6 { + margin: 0; +} + p { font-size: 0.7em; color: #888888; @@ -32,7 +36,7 @@ canvas { } .content { - width: 600px; + width: 600px; margin: auto; } From d76b0059621cb89aa4016d65afefac0a948d2bb0 Mon Sep 17 00:00:00 2001 From: Rafal Wilinski Date: Tue, 13 Sep 2016 23:55:59 +0200 Subject: [PATCH 05/14] Use classes instead of styles --- src/public/index.html | 8 ++++---- src/public/stylesheets/style.css | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/public/index.html b/src/public/index.html index 2b2879e..137f2c7 100644 --- a/src/public/index.html +++ b/src/public/index.html @@ -63,10 +63,10 @@

-

Status Codes
-
2xx
-
3xx
-
4xx
-
5xx
+
2xx
+
3xx
+
4xx
+
5xx
diff --git a/src/public/stylesheets/style.css b/src/public/stylesheets/style.css index d332dac..b152463 100644 --- a/src/public/stylesheets/style.css +++ b/src/public/stylesheets/style.css @@ -72,3 +72,19 @@ canvas { .span-controls { float: right; } + +.status-code-2xx { + color: #75D701; +} + +.status-code-3xx { + color: #47b8e0; +} + +.status-code-4xx { + color: #ffc952; +} + +.status-code-5xx { + color: #E53A40; +} From b94337b195ae9bebedbe9ea81fb5df7652f13ef2 Mon Sep 17 00:00:00 2001 From: Rafal Wilinski Date: Tue, 13 Sep 2016 23:56:38 +0200 Subject: [PATCH 06/14] fix eslint issue --- examples/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/index.js b/examples/index.js index 8dc3c41..1aad381 100644 --- a/examples/index.js +++ b/examples/index.js @@ -1,6 +1,7 @@ /* eslint no-console: "off" */ const express = require('express'); + const app = express(); const port = process.env.PORT || 3000; From adda3696802e55327f9cb97f1d7e6cc2e16afaac Mon Sep 17 00:00:00 2001 From: Rafal Wilinski Date: Tue, 13 Sep 2016 23:57:08 +0200 Subject: [PATCH 07/14] Fix eslint issue --- examples/tester.js | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/tester.js b/examples/tester.js index fbd6337..a2e7c3e 100644 --- a/examples/tester.js +++ b/examples/tester.js @@ -1,4 +1,5 @@ const request = require('request'); + const requestUrl = 'http://localhost:3000/return-status/'; const interval = 50; From 5d0794cbb576affb99bdc4572cce7c6b47eaad62 Mon Sep 17 00:00:00 2001 From: Rafal Wilinski Date: Tue, 13 Sep 2016 23:58:29 +0200 Subject: [PATCH 08/14] Remove unused color property --- src/public/javascripts/app.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/public/javascripts/app.js b/src/public/javascripts/app.js index f03fb89..9c8319a 100644 --- a/src/public/javascripts/app.js +++ b/src/public/javascripts/app.js @@ -44,13 +44,12 @@ var defaultOptions = { animation: false }; -var createChart = function (ctx, dataset, color) { +var createChart = function (ctx, dataset) { return new Chart(ctx, { type: 'line', data: { labels: [], datasets: dataset, - color: color ? color : 'black', }, options: defaultOptions }); From 05fc3522b4b2bc5b90fa6e421f1d9785ff7a21f9 Mon Sep 17 00:00:00 2001 From: Rafal Wilinski Date: Tue, 13 Sep 2016 23:59:36 +0200 Subject: [PATCH 09/14] Add trailing newline --- examples/tester.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/tester.js b/examples/tester.js index a2e7c3e..1aa0bb3 100644 --- a/examples/tester.js +++ b/examples/tester.js @@ -9,4 +9,4 @@ const makeDummyCall = () => setTimeout(() => { makeDummyCall(); }, interval); -makeDummyCall(); \ No newline at end of file +makeDummyCall(); From 79e600e838da33192930a801f0c6df14681b621c Mon Sep 17 00:00:00 2001 From: Rafal Wilinski Date: Wed, 14 Sep 2016 00:05:20 +0200 Subject: [PATCH 10/14] Add another zero-divide check --- src/public/javascripts/app.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/public/javascripts/app.js b/src/public/javascripts/app.js index 9c8319a..7831b99 100644 --- a/src/public/javascripts/app.js +++ b/src/public/javascripts/app.js @@ -175,6 +175,7 @@ socket.on('start', function (data) { if (data[defaultSpan].responses.length >= 2) { var deltaTime = lastResponseMetric.timestamp - data[defaultSpan].responses[data[defaultSpan].responses.length - 2].timestamp; + if (deltaTime < 1) deltaTime = 1000; rpsStat.textContent = (lastResponseMetric.count / deltaTime * 1000).toFixed(2); rpsChart.data.datasets[0].data = data[defaultSpan].responses.map(function (point) { return point.count / deltaTime * 1000; From b39e4a2d12cb218cdda2bef577ff3f257e68c9e2 Mon Sep 17 00:00:00 2001 From: Rafal Wilinski Date: Wed, 14 Sep 2016 23:03:23 +0200 Subject: [PATCH 11/14] Maintain safari compatibility --- src/public/javascripts/app.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/public/javascripts/app.js b/src/public/javascripts/app.js index 7831b99..5190bdc 100644 --- a/src/public/javascripts/app.js +++ b/src/public/javascripts/app.js @@ -98,7 +98,7 @@ var statusCodesChart = new Chart(statusCodesChartCtx, { options: defaultOptions }); -statusCodesChart.data.datasets.forEach((dataset, index) => { +statusCodesChart.data.datasets.forEach(function(dataset, index) { dataset.borderColor = statusCodesColors[index]; }); @@ -256,7 +256,7 @@ socket.on('stats', function (data) { charts.forEach(function (chart) { if (spans[defaultSpan].retention < chart.data.labels.length) { - chart.data.datasets.forEach((dataset) => { + chart.data.datasets.forEach(function(dataset) { dataset.data.shift(); }); From e9f72f4495aef088bb4858743554c0d61ab907fa Mon Sep 17 00:00:00 2001 From: Rafal Wilinski Date: Wed, 14 Sep 2016 23:09:40 +0200 Subject: [PATCH 12/14] Refactor stylesheet to use 2 spaces --- src/public/stylesheets/style.css | 95 ++++++++++++++++++-------------- 1 file changed, 54 insertions(+), 41 deletions(-) diff --git a/src/public/stylesheets/style.css b/src/public/stylesheets/style.css index b152463..b3e4eef 100644 --- a/src/public/stylesheets/style.css +++ b/src/public/stylesheets/style.css @@ -1,90 +1,103 @@ * { - font-family: Helvetica Neue, Helvetica, Arial, sans-serif; + font-family: Helvetica Neue, Helvetica, Arial, sans-serif; } h1 { - font-size: 3em; - color: #222222; - margin: 0; + font-size: 3em; + color: #222; + margin: 0; } h5 { - margin: 0; - color: #888888; + margin: 0; + color: #888; } h6 { - margin: 0; + margin: 0; } p { - font-size: 0.7em; - color: #888888; + font-size: 0.7em; + color: #888; } span { - cursor: pointer; - font-size: 10px; - margin-left: 5px; - border: 1px solid #DDD; - padding: 3px 10px 4px 10px; + cursor: pointer; + font-size: 10px; + margin-left: 5px; + border: 1px solid #DDD; + padding: 3px 10px 4px 10px; } canvas { - width: 400px; - height: 100px; + width: 400px; + height: 100px; } .content { - width: 600px; - margin: auto; + width: 600px; + margin: auto; } .active { - background: #eeeeee; + background: #eeeeee; } .stats-column { - flex: 0 0 200px; + flex: 0 0 200px; } .container { - display: flex; - flex-direction: row; - margin-top: 20px; - height: 100px; + display: flex; + flex-direction: row; + margin-top: 20px; + height: 100px; } .chart-container { - width: 400px; - height: 100px; + width: 400px; + height: 100px; } .footer { - position: fixed; - margin: auto; - text-align: center; - left: 0; - right: 0; - bottom: 0; + position: fixed; + margin: auto; + text-align: center; + left: 0; + right: 0; + bottom: 0; } .span-controls { - float: right; + float: right; } -.status-code-2xx { - color: #75D701; +.status-code { + margin-top: 2px; } -.status-code-3xx { - color: #47b8e0; +.status-code:before { + content: ''; + display: inline-block; + width: 8px; + height: 8px; + border-radius: 8px; + margin-right: 10px; } -.status-code-4xx { - color: #ffc952; +.status-code-2xx:before { + background-color: #75D701; } -.status-code-5xx { - color: #E53A40; +.status-code-3xx:before { + background-color: #47b8e0; +} + +.status-code-4xx:before { + background-color: #ffc952; +} + +.status-code-5xx:before { + background-color: #E53A40; } From 806829e4770bba78e5c29f0dc1d602d8edbd8148 Mon Sep 17 00:00:00 2001 From: Rafal Wilinski Date: Wed, 14 Sep 2016 23:09:51 +0200 Subject: [PATCH 13/14] Change status codes style --- src/public/index.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/public/index.html b/src/public/index.html index 137f2c7..f9cba41 100644 --- a/src/public/index.html +++ b/src/public/index.html @@ -63,10 +63,10 @@

-

Status Codes
-
2xx
-
3xx
-
4xx
-
5xx
+
2xx
+
3xx
+
4xx
+
5xx
From 0b856ff1eb210e7ba235031e8e4c69e204cff87d Mon Sep 17 00:00:00 2001 From: Rafal Wilinski Date: Wed, 14 Sep 2016 23:10:43 +0200 Subject: [PATCH 14/14] Bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f25be63..6a8cb31 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-status-monitor", - "version": "0.1.2", + "version": "0.1.3", "description": "Realtime Monitoring for Express-based Node applications", "main": "index.js", "keywords": [