Skip to content

Commit 5a39b44

Browse files
Merge pull request #52 from RafalWilinski/status-codes
Introduce Status Codes chart & fix undefined _view error in Chart.js
2 parents 20c3f12 + 0b856ff commit 5a39b44

File tree

7 files changed

+143
-43
lines changed

7 files changed

+143
-43
lines changed

examples/index.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@
33
const express = require('express');
44

55
const app = express();
6+
const port = process.env.PORT || 3000;
67

78
app.use(require('../index')({ path: '/' }));
89
app.use(require('express-favicon-short-circuit'));
910

10-
app.listen(3000, () => {
11-
console.log('listening on http://0.0.0.0:3000');
11+
// Example route throwing requested status code
12+
app.get('/return-status/:statusCode', (req, res) => res.sendStatus(req.params.statusCode));
13+
14+
app.listen(port, () => {
15+
console.log(`Listening on http://0.0.0.0:${port}`);
1216
});

examples/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@
1414
"license": "MIT",
1515
"dependencies": {
1616
"express": "^4.14.0",
17-
"express-favicon-short-circuit": "^1.1.0"
17+
"express-favicon-short-circuit": "^1.1.0",
18+
"request": "^2.74.0"
1819
},
1920
"scripts": {
20-
"start": "node index.js"
21+
"start": "node index.js",
22+
"benchmark": "node tester.js"
2123
},
2224
"repository": {
2325
"type": "git",

examples/tester.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
const request = require('request');
2+
3+
const requestUrl = 'http://localhost:3000/return-status/';
4+
const interval = 50;
5+
6+
const makeDummyCall = () => setTimeout(() => {
7+
const code = 200 + Math.random() * 399;
8+
request.get(`${requestUrl}${code}`);
9+
makeDummyCall();
10+
}, interval);
11+
12+
makeDummyCall();

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "express-status-monitor",
3-
"version": "0.1.2",
3+
"version": "0.1.3",
44
"description": "Realtime Monitoring for Express-based Node applications",
55
"main": "index.js",
66
"keywords": [

src/public/index.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,18 @@ <h1 id="rpsStat">-</h1>
6060
<canvas id="rpsChart" width="200" height="100"></canvas>
6161
</div>
6262
</div>
63+
<div class="container">
64+
<div class="stats-column">
65+
<h5>Status Codes</h5>
66+
<h6 class="status-code status-code-2xx">2xx</h6>
67+
<h6 class="status-code status-code-3xx">3xx</h6>
68+
<h6 class="status-code status-code-4xx">4xx</h6>
69+
<h6 class="status-code status-code-5xx">5xx</h6>
70+
</div>
71+
<div class="chart-container">
72+
<canvas id="statusCodesChart" width="200" height="100"></canvas>
73+
</div>
74+
</div>
6375
<div class="footer">
6476
<p>Made with &#9829; with Socket.io & Chart.js</p>
6577
</div>

src/public/javascripts/app.js

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Chart.defaults.global.elements.line.borderWidth = 2;
1010
var socket = io(location.protocol + '//' + location.hostname + ':' + location.port);
1111
var defaultSpan = 0;
1212
var spans = [];
13+
var statusCodesColors = ['#75D701', '#47b8e0', '#ffc952', '#E53A40'];
1314

1415
var defaultDataset = {
1516
label: '',
@@ -48,7 +49,7 @@ var createChart = function (ctx, dataset) {
4849
type: 'line',
4950
data: {
5051
labels: [],
51-
datasets: dataset
52+
datasets: dataset,
5253
},
5354
options: defaultOptions
5455
});
@@ -63,6 +64,7 @@ var memDataset = [Object.create(defaultDataset)];
6364
var loadDataset = [Object.create(defaultDataset)];
6465
var responseTimeDataset = [Object.create(defaultDataset)];
6566
var rpsDataset = [Object.create(defaultDataset)];
67+
var statusCodesDataset = [Object.create(defaultDataset)];
6668

6769
var cpuStat = document.getElementById('cpuStat');
6870
var memStat = document.getElementById('memStat');
@@ -75,14 +77,32 @@ var memChartCtx = document.getElementById("memChart");
7577
var loadChartCtx = document.getElementById("loadChart");
7678
var responseTimeChartCtx = document.getElementById("responseTimeChart");
7779
var rpsChartCtx = document.getElementById("rpsChart");
80+
var statusCodesChartCtx = document.getElementById("statusCodesChart");
7881

7982
var cpuChart = createChart(cpuChartCtx, cpuDataset);
8083
var memChart = createChart(memChartCtx, memDataset);
8184
var loadChart = createChart(loadChartCtx, loadDataset);
8285
var responseTimeChart = createChart(responseTimeChartCtx, responseTimeDataset);
8386
var rpsChart = createChart(rpsChartCtx, rpsDataset);
87+
var statusCodesChart = new Chart(statusCodesChartCtx, {
88+
type: 'line',
89+
data: {
90+
labels: [],
91+
datasets: [
92+
Object.create(defaultDataset),
93+
Object.create(defaultDataset),
94+
Object.create(defaultDataset),
95+
Object.create(defaultDataset)
96+
]
97+
},
98+
options: defaultOptions
99+
});
100+
101+
statusCodesChart.data.datasets.forEach(function(dataset, index) {
102+
dataset.borderColor = statusCodesColors[index];
103+
});
84104

85-
var charts = [cpuChart, memChart, loadChart, responseTimeChart, rpsChart];
105+
var charts = [cpuChart, memChart, loadChart, responseTimeChart, rpsChart, statusCodesChart];
86106

87107
var onSpanChange = function (e) {
88108
e.target.classList.add('active');
@@ -146,8 +166,16 @@ socket.on('start', function (data) {
146166
});
147167
responseTimeChart.data.labels = data[defaultSpan].responses.map(addTimestamp);
148168

169+
for(var i = 0; i < 4; i++) {
170+
statusCodesChart.data.datasets[i].data = data[defaultSpan].responses.map(function (point) {
171+
return point[i+2];
172+
});
173+
}
174+
statusCodesChart.data.labels = data[defaultSpan].responses.map(addTimestamp);
175+
149176
if (data[defaultSpan].responses.length >= 2) {
150177
var deltaTime = lastResponseMetric.timestamp - data[defaultSpan].responses[data[defaultSpan].responses.length - 2].timestamp;
178+
if (deltaTime < 1) deltaTime = 1000;
151179
rpsStat.textContent = (lastResponseMetric.count / deltaTime * 1000).toFixed(2);
152180
rpsChart.data.datasets[0].data = data[defaultSpan].responses.map(function (point) {
153181
return point.count / deltaTime * 1000;
@@ -181,6 +209,7 @@ socket.on('start', function (data) {
181209
socket.on('stats', function (data) {
182210
if (data.retention === spans[defaultSpan].retention && data.interval === spans[defaultSpan].interval) {
183211
var os = data.os;
212+
var responses = data.responses;
184213

185214
cpuStat.textContent = '0.0%';
186215
if (os) {
@@ -203,8 +232,6 @@ socket.on('stats', function (data) {
203232
loadChart.data.labels.push(os.timestamp);
204233
}
205234

206-
var responses = data.responses;
207-
208235
responseTimeStat.textContent = '0.00ms';
209236
if (responses) {
210237
responseTimeStat.textContent = responses.mean.toFixed(2) + 'ms';
@@ -214,17 +241,27 @@ socket.on('stats', function (data) {
214241

215242
if (responses) {
216243
var deltaTime = responses.timestamp - rpsChart.data.labels[rpsChart.data.labels.length - 1];
244+
if (deltaTime < 1) deltaTime = 1000;
217245
rpsStat.textContent = (responses.count / deltaTime * 1000).toFixed(2);
218246
rpsChart.data.datasets[0].data.push(responses.count / deltaTime * 1000);
219247
rpsChart.data.labels.push(responses.timestamp);
220248
}
221249

250+
if (responses) {
251+
for(var i = 0; i < 4; i++) {
252+
statusCodesChart.data.datasets[i].data.push(data.responses[i+2]);
253+
}
254+
statusCodesChart.data.labels.push(data.responses.timestamp);
255+
}
256+
222257
charts.forEach(function (chart) {
223258
if (spans[defaultSpan].retention < chart.data.labels.length) {
224-
chart.data.datasets[0].data.shift();
259+
chart.data.datasets.forEach(function(dataset) {
260+
dataset.data.shift();
261+
});
262+
225263
chart.data.labels.shift();
226264
}
227-
228265
chart.update();
229266
});
230267
}

src/public/stylesheets/style.css

Lines changed: 65 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,103 @@
11
* {
2-
font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
2+
font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
33
}
44

55
h1 {
6-
font-size: 3em;
7-
color: #222222;
8-
margin: 0;
6+
font-size: 3em;
7+
color: #222;
8+
margin: 0;
99
}
1010

1111
h5 {
12-
margin: 0;
13-
color: #888888;
12+
margin: 0;
13+
color: #888;
14+
}
15+
16+
h6 {
17+
margin: 0;
1418
}
1519

1620
p {
17-
font-size: 0.7em;
18-
color: #888888;
21+
font-size: 0.7em;
22+
color: #888;
1923
}
2024

2125
span {
22-
cursor: pointer;
23-
font-size: 10px;
24-
margin-left: 5px;
25-
border: 1px solid #DDD;
26-
padding: 3px 10px 4px 10px;
26+
cursor: pointer;
27+
font-size: 10px;
28+
margin-left: 5px;
29+
border: 1px solid #DDD;
30+
padding: 3px 10px 4px 10px;
2731
}
2832

2933
canvas {
30-
width: 400px;
31-
height: 100px;
34+
width: 400px;
35+
height: 100px;
3236
}
3337

3438
.content {
35-
width: 600px;
36-
margin: auto;
39+
width: 600px;
40+
margin: auto;
3741
}
3842

3943
.active {
40-
background: #eeeeee;
44+
background: #eeeeee;
4145
}
4246

4347
.stats-column {
44-
flex: 0 0 200px;
48+
flex: 0 0 200px;
4549
}
4650

4751
.container {
48-
display: flex;
49-
flex-direction: row;
50-
margin-top: 20px;
51-
height: 100px;
52+
display: flex;
53+
flex-direction: row;
54+
margin-top: 20px;
55+
height: 100px;
5256
}
5357

5458
.chart-container {
55-
width: 400px;
56-
height: 100px;
59+
width: 400px;
60+
height: 100px;
5761
}
5862

5963
.footer {
60-
position: fixed;
61-
margin: auto;
62-
text-align: center;
63-
left: 0;
64-
right: 0;
65-
bottom: 0;
64+
position: fixed;
65+
margin: auto;
66+
text-align: center;
67+
left: 0;
68+
right: 0;
69+
bottom: 0;
6670
}
6771

6872
.span-controls {
69-
float: right;
73+
float: right;
74+
}
75+
76+
.status-code {
77+
margin-top: 2px;
78+
}
79+
80+
.status-code:before {
81+
content: '';
82+
display: inline-block;
83+
width: 8px;
84+
height: 8px;
85+
border-radius: 8px;
86+
margin-right: 10px;
87+
}
88+
89+
.status-code-2xx:before {
90+
background-color: #75D701;
91+
}
92+
93+
.status-code-3xx:before {
94+
background-color: #47b8e0;
95+
}
96+
97+
.status-code-4xx:before {
98+
background-color: #ffc952;
99+
}
100+
101+
.status-code-5xx:before {
102+
background-color: #E53A40;
70103
}

0 commit comments

Comments
 (0)