Load Stat added
Showing
2 changed files
with
34 additions
and
82 deletions
... | @@ -63,27 +63,13 @@ | ... | @@ -63,27 +63,13 @@ |
63 | </div> | 63 | </div> |
64 | <div class="container"> | 64 | <div class="container"> |
65 | <div class="stats-column"> | 65 | <div class="stats-column"> |
66 | <h5>Requests per second</h5> | 66 | <h5>One Minute Load Avg</h5> |
67 | <h1 id="rpsStat">-</h1> | 67 | <h1 id="loadStat">-</h1> |
68 | </div> | 68 | </div> |
69 | <canvas id="rpsChart" width="400" height="100"></canvas> | 69 | <canvas id="loadChart" width="400" height="100"></canvas> |
70 | </div> | ||
71 | <div class="container"> | ||
72 | <div class="stats-column"> | ||
73 | <h5>Response Time Mean</h5> | ||
74 | <h1 id="responseTimeStat">- ms</h1> | ||
75 | </div> | ||
76 | <canvas id="responseTimeChart" width="400" height="100"></canvas> | ||
77 | </div> | ||
78 | <div class="container"> | ||
79 | <div class="stats-column"> | ||
80 | <h5>Response status codes</h5> | ||
81 | <h1 id="statusCodeStat">-</h1> | ||
82 | </div> | ||
83 | <canvas id="statusCodeChart" width="400" height="100"></canvas> | ||
84 | </div> | 70 | </div> |
85 | <div class="footer"> | 71 | <div class="footer"> |
86 | <p>Powered by Socket.io & Chart.js</p> | 72 | <p>Made with ♥ with Socket.io & Chart.js</p> |
87 | </div> | 73 | </div> |
88 | </div> | 74 | </div> |
89 | <script> | 75 | <script> |
... | @@ -106,28 +92,14 @@ | ... | @@ -106,28 +92,14 @@ |
106 | var memDataset = [{ | 92 | var memDataset = [{ |
107 | label: 'Memory Usage in MB', | 93 | label: 'Memory Usage in MB', |
108 | data: [], | 94 | data: [], |
109 | lineTension: 0.6, | 95 | lineTension: 0.2, |
110 | pointRadius: 0, | 96 | pointRadius: 0, |
111 | }]; | 97 | }]; |
112 | 98 | ||
113 | var responseTimeDataset = [{ | 99 | var loadDataset = [{ |
114 | label: 'Mean Response time', | 100 | label: '1 Minute Load', |
115 | data: [], | ||
116 | lineTension: 0.6, | ||
117 | pointRadius: 0, | ||
118 | }]; | ||
119 | |||
120 | var rpsDataset = [{ | ||
121 | label: 'Requests per second', | ||
122 | data: [], | ||
123 | lineTension: 0.6, | ||
124 | pointRadius: 0, | ||
125 | }]; | ||
126 | |||
127 | var statusCodesDataset = [{ | ||
128 | label: 'Memory Usage in MB', | ||
129 | data: [], | 101 | data: [], |
130 | lineTension: 0.6, | 102 | lineTension: 0.2, |
131 | pointRadius: 0, | 103 | pointRadius: 0, |
132 | }]; | 104 | }]; |
133 | 105 | ||
... | @@ -155,13 +127,12 @@ | ... | @@ -155,13 +127,12 @@ |
155 | 127 | ||
156 | var cpuStat = document.getElementById('cpuStat'); | 128 | var cpuStat = document.getElementById('cpuStat'); |
157 | var memStat = document.getElementById('memStat'); | 129 | var memStat = document.getElementById('memStat'); |
158 | var responseTimeStat = document.getElementById('responseTimeStat'); | 130 | var loadStat = document.getElementById('loadStat'); |
159 | var rpsStat = document.getElementById('rpsStat'); | 131 | |
160 | var cpuChartCtx = document.getElementById("cpuChart"); | 132 | var cpuChartCtx = document.getElementById("cpuChart"); |
161 | var memChartCtx = document.getElementById("memChart"); | 133 | var memChartCtx = document.getElementById("memChart"); |
162 | var rpsChartCtx = document.getElementById("rpsChart"); | 134 | var loadChartCtx = document.getElementById("loadChart"); |
163 | var responseTimeChartCtx = document.getElementById("responseTimeChart"); | 135 | |
164 | var statusCodeChartCtx = document.getElementById("statusCodeChart"); | ||
165 | var cpuChart = new Chart(cpuChartCtx, { | 136 | var cpuChart = new Chart(cpuChartCtx, { |
166 | type: 'line', | 137 | type: 'line', |
167 | data: { | 138 | data: { |
... | @@ -180,55 +151,32 @@ | ... | @@ -180,55 +151,32 @@ |
180 | options: defaultOptions | 151 | options: defaultOptions |
181 | }); | 152 | }); |
182 | 153 | ||
183 | var rpsChart = new Chart(rpsChartCtx, { | 154 | var loadChart = new Chart(loadChartCtx, { |
184 | type: 'line', | ||
185 | data: { | ||
186 | labels: labels, | ||
187 | datasets: responseTimeDataset, | ||
188 | }, | ||
189 | options: defaultOptions | ||
190 | }); | ||
191 | |||
192 | var responseTimeChart = new Chart(responseTimeChartCtx, { | ||
193 | type: 'line', | 155 | type: 'line', |
194 | data: { | 156 | data: { |
195 | labels: labels, | 157 | labels: labels, |
196 | datasets: responseTimeDataset, | 158 | datasets: loadDataset, |
197 | }, | 159 | }, |
198 | options: defaultOptions | 160 | options: defaultOptions |
199 | }); | 161 | }); |
200 | 162 | ||
201 | var statusCodeChart = new Chart(statusCodeChartCtx, { | ||
202 | type: 'line', | ||
203 | data: { | ||
204 | labels: labels, | ||
205 | datasets: statusCodesDataset, | ||
206 | }, | ||
207 | options: defaultOptions | ||
208 | }); | ||
209 | 163 | ||
210 | socket.on('stats', function (data) { | 164 | socket.on('stats', function (data) { |
211 | console.log(data); | 165 | console.log(data); |
212 | cpuStat.textContent = data.osStats[data.osStats.length - 1].cpu.toFixed(1) + '%'; | 166 | cpuStat.textContent = data.os[data.os.length - 1].cpu.toFixed(1) + '%'; |
213 | cpuChart.data.datasets[0].data = data.osStats.map(function(point) { return point.cpu; }); | 167 | cpuChart.data.datasets[0].data = data.os.map(function(point) { return point.cpu; }); |
214 | cpuChart.data.labels = data.osStats.map(function(point) { return point.timestamp; }); | 168 | cpuChart.data.labels = data.os.map(function(point) { return point.timestamp; }); |
215 | cpuChart.update(); | 169 | cpuChart.update(); |
216 | 170 | ||
217 | memStat.textContent = data.osStats[data.osStats.length - 1].memory.toFixed(1) + 'MB'; | 171 | memStat.textContent = data.os[data.os.length - 1].memory.toFixed(1) + 'MB'; |
218 | memChart.data.datasets[0].data = data.osStats.map(function(point) { return point.memory; }); | 172 | memChart.data.datasets[0].data = data.os.map(function(point) { return point.memory; }); |
219 | memChart.data.labels = data.osStats.map(function(point) { return point.timestamp; }); | 173 | memChart.data.labels = data.os.map(function(point) { return point.timestamp; }); |
220 | memChart.update(); | 174 | memChart.update(); |
221 | 175 | ||
222 | if (data.responses.length > 0) { | 176 | loadStat.textContent = data.os[data.os.length - 1].load[0].toFixed(2); |
223 | responseTimeStat.textContent = data.responses[data.responses.length - 1].mean.toFixed(1) + 'ms'; | 177 | loadChart.data.datasets[0].data = data.os.map(function(point) { return point.load[0]; }); |
224 | responseTimeChart.data.datasets[0].data = data.responses.map(function (point) { | 178 | loadChart.data.labels = data.os.map(function(point) { return point.timestamp; }); |
225 | return point.mean; | 179 | loadChart.update(); |
226 | }); | ||
227 | responseTimeChart.data.labels = data.responses.map(function (point) { | ||
228 | return point.timestamp; | ||
229 | }); | ||
230 | responseTimeChart.update(); | ||
231 | } | ||
232 | }); | 180 | }); |
233 | </script> | 181 | </script> |
234 | </body> | 182 | </body> | ... | ... |
... | @@ -2,6 +2,7 @@ | ... | @@ -2,6 +2,7 @@ |
2 | 'use strict'; | 2 | 'use strict'; |
3 | 3 | ||
4 | const path = require('path'); | 4 | const path = require('path'); |
5 | const os = require('os'); | ||
5 | const onHeaders = require('on-headers'); | 6 | const onHeaders = require('on-headers'); |
6 | const pidusage = require('pidusage'); | 7 | const pidusage = require('pidusage'); |
7 | 8 | ||
... | @@ -20,10 +21,11 @@ | ... | @@ -20,10 +21,11 @@ |
20 | 21 | ||
21 | // Convert from B to MB | 22 | // Convert from B to MB |
22 | stat.memory = stat.memory / 1024 / 1024; | 23 | stat.memory = stat.memory / 1024 / 1024; |
24 | stat.load = os.loadavg(); | ||
23 | 25 | ||
24 | span.osStats.push(stat); | 26 | span.os.push(stat); |
25 | if (span.osStats.length >= span.retention) span.osStats.shift(); | 27 | |
26 | if (span.responses[0] && span.responses[0].timestamp + (span.interval * span.retention * 1000) < Date.now()) span.responses.shift(); | 28 | if (span.os.length >= span.retention) span.os.shift(); |
27 | 29 | ||
28 | sendMetrics(io, span); | 30 | sendMetrics(io, span); |
29 | }); | 31 | }); |
... | @@ -31,7 +33,7 @@ | ... | @@ -31,7 +33,7 @@ |
31 | 33 | ||
32 | const sendMetrics = (io, span) => { | 34 | const sendMetrics = (io, span) => { |
33 | io.emit('stats', { | 35 | io.emit('stats', { |
34 | osStats: span.osStats, | 36 | os: span.os, |
35 | responses: span.responses, | 37 | responses: span.responses, |
36 | }); | 38 | }); |
37 | }; | 39 | }; |
... | @@ -60,7 +62,7 @@ | ... | @@ -60,7 +62,7 @@ |
60 | }); | 62 | }); |
61 | 63 | ||
62 | config.spans.forEach((span) => { | 64 | config.spans.forEach((span) => { |
63 | span.osStats = []; | 65 | span.os = []; |
64 | span.responses = []; | 66 | span.responses = []; |
65 | setInterval(() => gatherOsMetrics(io, span), span.interval * 1000); | 67 | setInterval(() => gatherOsMetrics(io, span), span.interval * 1000); |
66 | }); | 68 | }); |
... | @@ -76,9 +78,11 @@ | ... | @@ -76,9 +78,11 @@ |
76 | const category = Math.floor(res.statusCode / 100); | 78 | const category = Math.floor(res.statusCode / 100); |
77 | 79 | ||
78 | config.spans.forEach((span) => { | 80 | config.spans.forEach((span) => { |
79 | if (span.responses[span.responses.length - 1] !== undefined && | 81 | const last = span.responses[span.responses.length - 1]; |
82 | if (last !== undefined && | ||
80 | span.responses[span.responses.length - 1].timestamp / 1000 + span.interval > Date.now() / 1000) { | 83 | span.responses[span.responses.length - 1].timestamp / 1000 + span.interval > Date.now() / 1000) { |
81 | span.responses[span.responses.length - 1][category]++; | 84 | span.responses[span.responses.length - 1][category]++; |
85 | span.responses[span.responses.length - 1].mean = responseTime; | ||
82 | span.responses[span.responses.length - 1].count++; | 86 | span.responses[span.responses.length - 1].count++; |
83 | } else { | 87 | } else { |
84 | span.responses.push({ | 88 | span.responses.push({ | ... | ... |
-
Please register or sign in to post a comment