Skip to content

Commit

Permalink
Add event loop and heap statistics
Browse files Browse the repository at this point in the history
  • Loading branch information
RafalWilinski committed Apr 21, 2020
1 parent 8c1398d commit cd01089
Show file tree
Hide file tree
Showing 8 changed files with 210 additions and 118 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ chartVisibility: {
cpu: true,
mem: true,
load: true,
eventLoop: true,
heap: true,
responseTime: true,
rps: true,
statusCodes: true
Expand Down
15 changes: 14 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "express-status-monitor",
"version": "1.2.11",
"version": "1.3.0",
"description": "Realtime Monitoring for Express-based Node applications",
"main": "index.js",
"keywords": [
Expand Down Expand Up @@ -59,6 +59,7 @@
"dependencies": {
"axios": "0.19.2",
"debug": "4.1.1",
"event-loop-stats": "1.2.0",
"handlebars": "^4.7.6",
"on-headers": "1.0.2",
"pidusage": "2.0.18",
Expand Down
4 changes: 3 additions & 1 deletion src/helpers/default-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ module.exports = {
cpu: true,
mem: true,
load: true,
heap: true,
eventLoop: true,
responseTime: true,
rps: true,
statusCodes: true,
},
ignoreStartsWith: '/admin',
healthChecks: []
healthChecks: [],
};
6 changes: 5 additions & 1 deletion src/helpers/gather-os-metrics.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const pidusage = require('pidusage');
const os = require('os');
const v8 = require('v8');
const eventLoopStats = require('event-loop-stats');
const sendMetrics = require('./send-metrics');
const debug = require('debug')('express-status-monitor');

Expand All @@ -26,9 +28,11 @@ module.exports = (io, span) => {
stat.memory = stat.memory / 1024 / 1024;
stat.load = os.loadavg();
stat.timestamp = Date.now();
stat.heap = v8.getHeapStatistics();
stat.loop = eventLoopStats.sense();

span.os.push(stat);
if (!span.responses[0] || last.timestamp + (span.interval * 1000) < Date.now()) {
if (!span.responses[0] || last.timestamp + span.interval * 1000 < Date.now()) {
span.responses.push(defaultResponse);
}

Expand Down
11 changes: 6 additions & 5 deletions src/helpers/socket-io-init.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const addSocketEvents = (socket, config) => {
socket.on('esm_change', () => {
socket.emit('esm_start', config.spans);
});
}
};

module.exports = (server, config) => {
if (io === null || io === undefined) {
Expand All @@ -22,10 +22,11 @@ module.exports = (server, config) => {
io = socketIo(server);
}

io.on('connection', socket => {
io.on('connection', (socket) => {
if (config.authorize) {
config.authorize(socket)
.then(authorized => {
config
.authorize(socket)
.then((authorized) => {
if (!authorized) socket.disconnect('unauthorized');
else addSocketEvents(socket, config);
})
Expand All @@ -35,7 +36,7 @@ module.exports = (server, config) => {
}
});

config.spans.forEach(span => {
config.spans.forEach((span) => {
span.os = [];
span.responses = [];
const interval = setInterval(() => gatherOsMetrics(io, span), span.interval * 1000);
Expand Down
199 changes: 108 additions & 91 deletions src/public/index.html
Original file line number Diff line number Diff line change
@@ -1,97 +1,114 @@
<!DOCTYPE html>
<html>
<head>
<title>{{title}}</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.2.2/Chart.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.5/socket.io.min.js"></script>
<style>
{{{style}}}
</style>
</head>
<body class="{{bodyClasses}}">
<div class="content">
<div class="header">
<b>{{title}}</b>
<div id="span-controls" class="span-controls">
</div>
</div>
<div class="container cpu">
<div class="stats-column">
<h5>CPU Usage</h5>
<h1 id="cpuStat">- %</h1>
</div>
<div class="chart-container">
<canvas id="cpuChart" width="400" height="100"></canvas>
</div>
</div>
<div class="container mem">
<div class="stats-column">
<h5>Memory Usage</h5>
<h1 id="memStat">- %</h1>
</div>
<div class="chart-container">
<canvas id="memChart" width="200" height="100"></canvas>
</div>
</div>
<div class="container load">
<div class="stats-column">
<h5>One Minute Load Avg</h5>
<h1 id="loadStat">-</h1>
</div>
<div class="chart-container">
<canvas id="loadChart" width="200" height="100"></canvas>
</div>
</div>
<div class="container responseTime">
<div class="stats-column">
<h5>Response Time</h5>
<h1 id="responseTimeStat">-</h1>
</div>
<div class="chart-container">
<canvas id="responseTimeChart" width="200" height="100"></canvas>
</div>
</div>
<div class="container rps">
<div class="stats-column">
<h5>Requests per Second</h5>
<h1 id="rpsStat">-</h1>
</div>
<div class="chart-container">
<canvas id="rpsChart" width="200" height="100"></canvas>
</div>
</div>
<div class="container statusCodes">
<div class="stats-column">
<h5>Status Codes</h5>
<h6 class="status-code status-code-2xx">2xx</h6>
<h6 class="status-code status-code-3xx">3xx</h6>
<h6 class="status-code status-code-4xx">4xx</h6>
<h6 class="status-code status-code-5xx">5xx</h6>
</div>
<div class="chart-container">
<canvas id="statusCodesChart" width="200" height="100"></canvas>
</div>
</div>
<div class="container healthChecks">
{{#each healthCheckResults}}
<div class="health-check-row">
<div class="health-check-title-column">
<h5><a href="{{path}}">{{path}}</a></h5>
<head>
<title>{{title}}</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.2.2/Chart.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.5/socket.io.min.js"></script>
<style>
{{{style}}}
</style>
</head>
<body class="{{bodyClasses}}">
<div class="content">
<div class="header">
<b>{{title}}</b>
<div id="span-controls" class="span-controls"></div>
</div>
<div class="container cpu">
<div class="stats-column">
<h5>CPU Usage</h5>
<h1 id="cpuStat">- %</h1>
</div>
<div class="chart-container">
<canvas id="cpuChart" width="400" height="100"></canvas>
</div>
<div class="health-check-status-container {{status}}">
<h1>{{status}}</h1>
</div>
<div class="container mem">
<div class="stats-column">
<h5>Memory Usage</h5>
<h1 id="memStat">- %</h1>
</div>
<div class="chart-container">
<canvas id="memChart" width="200" height="100"></canvas>
</div>
</div>
<div class="container heap-size">
<div class="stats-column">
<h5>Heap Usage</h5>
<h1 id="heapStat">- %</h1>
</div>
<div class="chart-container">
<canvas id="heapChart" width="200" height="100"></canvas>
</div>
</div>
<div class="container load">
<div class="stats-column">
<h5>One Minute Load Avg</h5>
<h1 id="loadStat">-</h1>
</div>
<div class="chart-container">
<canvas id="loadChart" width="200" height="100"></canvas>
</div>
</div>
<div class="container eventLoop">
<div class="stats-column">
<h5>Spent in Event Loop</h5>
<h1 id="eventLoopStat">ms</h1>
</div>
<div class="chart-container">
<canvas id="eventLoopChart" width="200" height="100"></canvas>
</div>
</div>
<div class="container responseTime">
<div class="stats-column">
<h5>Response Time</h5>
<h1 id="responseTimeStat">-</h1>
</div>
<div class="chart-container">
<canvas id="responseTimeChart" width="200" height="100"></canvas>
</div>
</div>
<div class="container rps">
<div class="stats-column">
<h5>Requests per Second</h5>
<h1 id="rpsStat">-</h1>
</div>
<div class="chart-container">
<canvas id="rpsChart" width="200" height="100"></canvas>
</div>
</div>
<div class="container statusCodes">
<div class="stats-column">
<h5>Status Codes</h5>
<h6 class="status-code status-code-2xx">2xx</h6>
<h6 class="status-code status-code-3xx">3xx</h6>
<h6 class="status-code status-code-4xx">4xx</h6>
<h6 class="status-code status-code-5xx">5xx</h6>
</div>
<div class="chart-container">
<canvas id="statusCodesChart" width="200" height="100"></canvas>
</div>
</div>
<div class="container healthChecks">
{{#each healthCheckResults}}
<div class="health-check-row">
<div class="health-check-title-column">
<h5><a href="{{path}}">{{path}}</a></h5>
</div>
<div class="health-check-status-container {{status}}">
<h1>{{status}}</h1>
</div>
</div>
{{/each}}
</div>
<div class="footer">
<p>Made with &#9829; with Socket.io & Chart.js</p>
</div>
</div>
{{/each}}
</div>
<div class="footer">
<p>Made with &#9829; with Socket.io & Chart.js</p>
</div>
</div>
<script>
var port = '{{port}}';
var socketPath = '{{socketPath}}';
{{{script}}}
</script>
</body>
<script>
var port = '{{port}}';
var socketPath = '{{socketPath}}';
{{{script}}}
</script>
</body>
</html>
Loading

0 comments on commit cd01089

Please sign in to comment.