Socket
Socket
Sign inDemoInstall

express-status-monitor

Package Overview
Dependencies
Maintainers
1
Versions
42
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

express-status-monitor - npm Package Compare versions

Comparing version 0.1.5 to 0.1.6

.eslintignore

5

.eslintrc.json

@@ -12,4 +12,3 @@ {

"import/no-extraneous-dependencies": [
"error",
{
"error", {
"peerDependencies": true

@@ -20,2 +19,2 @@ }

}
}
}

14

examples/index.js
/* eslint no-console: "off" */
const socketIoPort = 2222;
const express = require('express');
// This is optional. If your server uses socket.io already, pass it to config as `webserver` along with it's port.
const socketio = require('socket.io')(socketIoPort);
const app = express();
const port = process.env.PORT || 3000;
app.use(require('../index')({ path: '/' }));
app.use(require('../index')({
path: '/',
// Use existing socket.io instance.
// websocket: socketio,
// Pass socket.io instance port down to config.
// Use only if you're passing your own instance.
// port: socketIoPort,
}));
app.use(require('express-favicon-short-circuit'));

@@ -10,0 +22,0 @@

const request = require('request');
const requestUrl = 'http://localhost:3000/return-status/';
const port = 3000;
const requestUrl = `http://localhost:${port}/return-status/`;
const interval = 50;

@@ -9,2 +11,3 @@

request.get(`${requestUrl}${code}`);
makeDummyCall();

@@ -11,0 +14,0 @@ }, interval);

@@ -1,1 +0,1 @@

module.exports = require('./src/middleware-wrapper');
module.exports = require('./src/middleware-wrapper');
{
"name": "express-status-monitor",
"version": "0.1.5",
"version": "0.1.6",
"description": "Realtime Monitoring for Express-based Node applications",

@@ -46,15 +46,27 @@ "main": "index.js",

"on-headers": "^1.0.1",
"pidusage": "^1.0.8",
"socket.io": "^1.4.8"
"pidusage": "^1.1.0",
"socket.io": "^1.5.1"
},
"scripts": {
"coverage": "istanbul cover _mocha test -- --recursive",
"test": "mocha --recursive"
"test": "mocha --recursive",
"snyk-protect": "snyk protect",
"prepublish": "npm run snyk-protect",
"example": "cd examples && npm start",
"eslint": "eslint ."
},
"devDependencies": {
"bithound": "^1.7.0",
"chai": "^3.5.0",
"eslint": "^3.9.1",
"eslint-config-airbnb": "^12.0.0",
"eslint-plugin-import": "^1.16.0",
"eslint-plugin-jsx-a11y": "^2.2.3",
"eslint-plugin-react": "^6.5.0",
"istanbul": "^0.4.5",
"mocha": "^3.0.2",
"sinon": "^1.17.5"
}
"sinon": "^1.17.5",
"snyk": "^1.19.1"
},
"snyk": true
}
# express-status-monitor
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/express-status-monitor/Lobby/?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
[![express-status-monitor on npm](https://img.shields.io/npm/v/express-status-monitor.svg)](https://www.npmjs.com/express-status-monitor)
[![npm](https://img.shields.io/npm/dt/express-status-monitor.svg)](https://img.shields.io/npm/dt/express-status-monitor.svg)
[![bitHound Overall Score](https://www.bithound.io/github/RafalWilinski/express-status-monitor/badges/score.svg)](https://www.bithound.io/github/RafalWilinski/express-status-monitor)
[![CircleCI](https://img.shields.io/circleci/project/github/RafalWilinski/express-status-monitor/master.svg)](https://circleci.com/gh/RafalWilinski/express-status-monitor)
Simple, self-hosted module based on Socket.io and Chart.js to report realtime server metrics for Express-based node servers.

@@ -38,2 +44,3 @@

path: '/status',
websocket: existingSocketIoInstance,
spans: [{

@@ -73,2 +80,6 @@ interval: 1, // Every second

## Using module with socket.io in project
If you're using socket.io in your project, this module could break your project because this module by default will spawn its own socket.io instance. To mitigate that, fill websocket parameter with your main socket.io instance as well as port parameter.
## Tests and coverage

@@ -75,0 +86,0 @@

@@ -18,2 +18,4 @@ module.exports = {

],
port: null,
websocket: null,
};
module.exports = (statusCode, startTime, spans) => {
const diff = process.hrtime(startTime);
const responseTime = diff[0] * 1e3 + diff[1] * 1e-6;
const responseTime = ((diff[0] * 1e3) + diff[1]) * 1e-6;
const category = Math.floor(statusCode / 100);

@@ -8,6 +8,6 @@

const last = span.responses[span.responses.length - 1];
if (last !== undefined && last.timestamp / 1000 + span.interval > Date.now() / 1000) {
last[category]++;
last.count++;
last.mean = last.mean + ((responseTime - last.mean) / last.count);
if (last !== undefined && (last.timestamp / 1000) + span.interval > Date.now() / 1000) {
last[category] += 1;
last.count += 1;
last.mean += ((responseTime - last.mean) / last.count);
} else {

@@ -14,0 +14,0 @@ span.responses.push({

module.exports = (io, span) => {
io.emit('stats', {
io.emit('esm_stats', {
os: span.os[span.os.length - 2],

@@ -4,0 +4,0 @@ responses: span.responses[span.responses.length - 2],

/* eslint strict: "off" */
'use strict';

@@ -9,14 +10,18 @@

module.exports = (server, spans) => {
module.exports = (server, config) => {
if (io === null || io === undefined) {
io = socketIo(server);
if (config.websocket !== null) {
io = config.websocket;
} else {
io = socketIo(server);
}
io.on('connection', (socket) => {
socket.emit('start', spans);
socket.on('change', () => {
socket.emit('start', spans);
socket.emit('esm_start', config.spans);
socket.on('esm_change', () => {
socket.emit('esm_start', config.spans);
});
});
spans.forEach((span) => {
config.spans.forEach((span) => {
span.os = [];

@@ -23,0 +28,0 @@ span.responses = [];

@@ -14,3 +14,7 @@ const defaultConfig = require('./default-config');

config.port = (typeof config.port === 'number') ? config.port : defaultConfig.port;
config.websocket = (typeof config.websocket === 'object') ? config.websocket : defaultConfig.websocket;
return config;
};

@@ -15,2 +15,3 @@ const fs = require('fs');

.replace(/{{title}}/g, config.title)
.replace(/{{port}}/g, config.port)
.replace(/{{script}}/g, fs.readFileSync(path.join(__dirname, '/public/javascripts/app.js')))

@@ -20,3 +21,3 @@ .replace(/{{style}}/g, fs.readFileSync(path.join(__dirname, '/public/stylesheets/style.css')));

return (req, res, next) => {
socketIoInit(req.socket.server, config.spans);
socketIoInit(req.socket.server, config);

@@ -27,3 +28,3 @@ const startTime = process.hrtime();

} else {
onHeaders(res, () => { onHeadersListener(res.statusCode, startTime, config.spans) });
onHeaders(res, () => { onHeadersListener(res.statusCode, startTime, config.spans); });
next();

@@ -30,0 +31,0 @@ }

@@ -0,1 +1,7 @@

/*
eslint-disable no-plusplus, no-var, strict, vars-on-top, prefer-template,
func-names, prefer-arrow-callback, no-loop-func
*/
/* global Chart, location, document, port, parseInt, io */
'use strict';

@@ -6,7 +12,7 @@

Chart.defaults.global.legend.display = false;
Chart.defaults.global.elements.line.backgroundColor = "rgba(0,0,0,0)";
Chart.defaults.global.elements.line.borderColor = "rgba(0,0,0,0.9)";
Chart.defaults.global.elements.line.backgroundColor = 'rgba(0,0,0,0)';
Chart.defaults.global.elements.line.borderColor = 'rgba(0,0,0,0.9)';
Chart.defaults.global.elements.line.borderWidth = 2;
var socket = io(location.protocol + '//' + location.hostname + ':' + location.port);
var socket = io(location.protocol + '//' + location.hostname + ':' + (port || location.port));
var defaultSpan = 0;

@@ -20,3 +26,3 @@ var spans = [];

lineTension: 0.2,
pointRadius: 0
pointRadius: 0,
};

@@ -28,4 +34,4 @@

ticks: {
beginAtZero: true
}
beginAtZero: true,
},
}],

@@ -35,15 +41,15 @@ xAxes: [{

time: {
unitStepSize: 30
unitStepSize: 30,
},
gridLines: {
display: false
}
}]
display: false,
},
}],
},
tooltips: {
enabled: false
enabled: false,
},
responsive: true,
maintainAspectRatio: false,
animation: false
animation: false,
};

@@ -58,3 +64,3 @@

},
options: defaultOptions
options: defaultOptions,
});

@@ -72,3 +78,2 @@ };

var rpsDataset = [Object.create(defaultDataset)];
var statusCodesDataset = [Object.create(defaultDataset)];

@@ -81,8 +86,8 @@ var cpuStat = document.getElementById('cpuStat');

var cpuChartCtx = document.getElementById("cpuChart");
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 cpuChartCtx = document.getElementById('cpuChart');
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');

@@ -102,9 +107,9 @@ var cpuChart = createChart(cpuChartCtx, cpuDataset);

Object.create(defaultDataset),
Object.create(defaultDataset)
]
Object.create(defaultDataset),
],
},
options: defaultOptions
options: defaultOptions,
});
statusCodesChart.data.datasets.forEach(function(dataset, index) {
statusCodesChart.data.datasets.forEach(function (dataset, index) {
dataset.borderColor = statusCodesColors[index];

@@ -117,3 +122,3 @@ });

e.target.classList.add('active');
defaultSpan = parseInt(e.target.id);
defaultSpan = parseInt(e.target.id, 10);

@@ -125,6 +130,6 @@ var otherSpans = document.getElementsByTagName('span');

socket.emit('change');
socket.emit('esm_change');
};
socket.on('start', function (data) {
socket.on('esm_start', function (data) {
// Remove last element of Array because it contains malformed responses data.

@@ -179,5 +184,5 @@ // To keep consistency we also remove os data.

for(var i = 0; i < 4; i++) {
for (var i = 0; i < 4; i++) {
statusCodesChart.data.datasets[i].data = data[defaultSpan].responses.map(function (point) {
return point[i+2];
return point[i + 2];
});

@@ -188,7 +193,8 @@ }

if (data[defaultSpan].responses.length >= 2) {
var deltaTime = lastResponseMetric.timestamp - data[defaultSpan].responses[data[defaultSpan].responses.length - 2].timestamp;
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);
rpsStat.textContent = ((lastResponseMetric.count / deltaTime) * 1000).toFixed(2);
rpsChart.data.datasets[0].data = data[defaultSpan].responses.map(function (point) {
return point.count / deltaTime * 1000;
return (point.count / deltaTime) * 1000;
});

@@ -207,7 +213,7 @@ rpsChart.data.labels = data[defaultSpan].responses.map(addTimestamp);

retention: span.retention,
interval: span.interval
interval: span.interval,
});
var spanNode = document.createElement('span');
var textNode = document.createTextNode((span.retention * span.interval) / 60 + "M");
var textNode = document.createTextNode(((span.retention * span.interval) / 60) + 'M');
spanNode.appendChild(textNode);

@@ -222,4 +228,5 @@ spanNode.setAttribute('id', index);

socket.on('stats', function (data) {
if (data.retention === spans[defaultSpan].retention && data.interval === spans[defaultSpan].interval) {
socket.on('esm_stats', function (data) {
if (data.retention === spans[defaultSpan].retention &&
data.interval === spans[defaultSpan].interval) {
var os = data.os;

@@ -259,4 +266,4 @@ var responses = data.responses;

if (deltaTime < 1) deltaTime = 1000;
rpsStat.textContent = (responses.count / deltaTime * 1000).toFixed(2);
rpsChart.data.datasets[0].data.push(responses.count / deltaTime * 1000);
rpsStat.textContent = ((responses.count / deltaTime) * 1000).toFixed(2);
rpsChart.data.datasets[0].data.push((responses.count / deltaTime) * 1000);
rpsChart.data.labels.push(responses.timestamp);

@@ -266,4 +273,4 @@ }

if (responses) {
for(var i = 0; i < 4; i++) {
statusCodesChart.data.datasets[i].data.push(data.responses[i+2]);
for (var i = 0; i < 4; i++) {
statusCodesChart.data.datasets[i].data.push(data.responses[i + 2]);
}

@@ -275,3 +282,3 @@ statusCodesChart.data.labels.push(data.responses.timestamp);

if (spans[defaultSpan].retention < chart.data.labels.length) {
chart.data.datasets.forEach(function(dataset) {
chart.data.datasets.forEach(function (dataset) {
dataset.data.shift();

@@ -285,2 +292,2 @@ });

}
});
});

@@ -17,3 +17,3 @@ const chai = require('chai');

sinon.assert.calledWith(io.emit, 'stats');
sinon.assert.calledWith(io.emit, 'esm_stats');
});

@@ -20,0 +20,0 @@ });

@@ -20,3 +20,3 @@ const chai = require('chai');

socketIoInit({}, spans);
socketIoInit({}, defaultConfig);

@@ -23,0 +23,0 @@ spans.forEach((span) => {

@@ -0,1 +1,2 @@

/* eslint-disable no-unused-expressions */
const chai = require('chai');

@@ -24,6 +25,14 @@

});
it('then port === null', () => {
chai.expect(config.port).to.be.null;
});
it('then websocket === null', () => {
chai.expect(config.websocket).to.be.null;
});
});
describe('when config is invalid', () => {
const config = validate({ title: true, path: false, spans: 'not-an-array' });
const config = validate({ title: true, path: false, spans: 'not-an-array', port: 'abc', websocket: false });

@@ -41,6 +50,14 @@ it(`then title === ${defaultConfig.title}`, () => {

});
it('then port === null', () => {
chai.expect(config.port).to.be.null;
});
it('then websocket === null', () => {
chai.expect(config.websocket).to.be.null;
});
});
describe('when config is valid', () => {
const customConfig = { title: 'Custom title', path: '/custom-path', spans: [{}, {}, {}] }
const customConfig = { title: 'Custom title', path: '/custom-path', spans: [{}, {}, {}], port: 9999, websocket: {} };
const config = validate(customConfig);

@@ -59,4 +76,12 @@

});
it('then websocket === {}', () => {
config.websocket.should.deep.equal({});
});
it(`then port === ${customConfig.port}`, () => {
config.port.should.equal(customConfig.port);
});
});
});
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc