Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

monitor-dog

Package Overview
Dependencies
Maintainers
2
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

monitor-dog - npm Package Compare versions

Comparing version 1.3.0 to 1.4.0

lib/timer.js

131

lib/monitor.js

@@ -13,2 +13,3 @@ 'use strict';

var Timer = require('./timer');
var SocketsMonitor = require('./sockets-monitor');

@@ -75,3 +76,5 @@

*/
['set', 'increment', 'decrement', 'histogram', 'gauge'].forEach(function (method) {
var methodNames = ['set', 'increment', 'decrement', 'histogram', 'gauge'];
methodNames.forEach(function (method) {
Monitor.prototype[method] = function () {

@@ -91,2 +94,96 @@ var args = Array.prototype.slice.call(arguments);

/**
* Sends an event to datadog.
*
* @example
* monitor.event({
* title: 'Docker Build Failure',
* text: 'Failed to build container ' + name + ' with id ' + id
* });
*
* @param {string} opt.title Title for the event (required).
* @param {string} opt.text Text for the event (required).
* @param {number} opt.date_happened Optional timestamp for when the event
* occurred.
* @param {string} opt.hostname Optional host name for the event.
* @param {string} opt.aggregation_key Optional grouping key for the event.
* @param {string} opt.priority Optional priority can be 'normal' or 'low'.
* @param {string} opt.source_type_name Optional source type for the event.
* @param {string} opt.alert_type Optional alert level can be 'error',
* 'warning', 'info', 'success'.
* @param {Array} opt.tags Array of tags to associate with the event.
* @throws Error If opt.title or opt.text are missing.
* @see http://docs.datadoghq.com/guides/dogstatsd/#datagram-format
*/
Monitor.prototype.event = function (opt) {
if (!isObject(opt)) {
throw new Error('Missing required options');
}
if (!opt.title) {
throw new Error('Missing required title option');
}
if (!opt.text) {
throw new Error('Missing required text option');
}
//_e{title.length,text.length}:title|text
var buf = [
'_e{', opt.title.length, ',', opt.text.length, '}:',
sanitize(opt.title), '|', sanitize(opt.text)
];
//|d:date_happened
if (isNumber(opt.date_happened)) {
buf.push('|d:', parseInt(opt.date_happened));
}
//|h:hostname
pushIfString('|h:', opt.hostname);
//|k:aggregation_key
pushIfString('|k:', opt.aggregation_key);
//|p:priority
if (
isString(opt.priority) &&
(opt.priority === 'low' || opt.priority === 'normal')
) {
buf.push('|p:', opt.priority);
}
//|t:alert_type
if (
isString(opt.alert_type) &&
(
opt.alert_type === 'error' ||
opt.alert_type === 'warning' ||
opt.alert_type === 'info' ||
opt.alert_type === 'success'
)
) {
buf.push('|t:', opt.alert_type);
}
//|#tag1,tag2
if (Array.isArray(opt.tags)) {
var tags = opt.tags.map(function (tag) {
return tag.replace(/,/g, '');
}).join(',');
buf.push('|#', tags);
}
// Send the data using the dogstatsd client
this.client.send_data(buf.join(''));
function sanitize(s) {
return s.replace(/[|]/g, '');
}
function pushIfString(prefix, value) {
if (isString(value)) {
buf.push(prefix, sanitize(value));
}
}
};
/**
* Creates a new timer for the given histogram name.

@@ -155,33 +252,1 @@ *

};
/**
* Timer class for performing time calculations through the monitor
* module.
* @class
*/
function Timer (callback, start) {
this.callback = callback;
if (!exists(start) || start !== false) {
this.start();
}
}
/**
* Starts the timer.
*/
Timer.prototype.start = function () {
if (this.startDate) {
return;
}
this.startDate = new Date();
};
/**
* Stops the timer and sends information through datadog.
*/
Timer.prototype.stop = function () {
if (!this.startDate) {
return;
}
this.callback(new Date() - this.startDate);
};
{
"name": "monitor-dog",
"version": "1.3.0",
"version": "1.4.0",
"description": "A helpful wrapper for dogstatsd.",

@@ -5,0 +5,0 @@ "main": "index.js",

'use strict';
var monitor = require('../../index.js');
var clientMethods = ['set', 'increment', 'decrement', 'histogram', 'gauge'];
var clientMethods = [
'set', 'increment', 'decrement', 'histogram', 'gauge', 'send_data'
];
var sinon = require('sinon');

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

@@ -23,85 +23,84 @@ 'use strict';

var ctx = {};
describe('monitor-dog', function() {
describe('sockets-monitor', function() {
beforeEach(function (done) {
dogstatsd.stubAll();
ctx.originalGlobalAgent = http.globalAgent;
describe('SocketsMonitor', function() {
beforeEach(function (done) {
dogstatsd.stubAll();
ctx.originalGlobalAgent = http.globalAgent;
done();
});
afterEach(function (done) {
dogstatsd.restoreAll();
http.globalAgent = ctx.originalGlobalAgent;
done();
});
describe('constructor', function() {
it('should use given socket prefix', function(done) {
var socketMonitor = new SocketsMonitor({}, 'prefix', 1000);
expect(socketMonitor.prefix).to.equal('prefix');
done();
});
afterEach(function (done) {
dogstatsd.restoreAll();
http.globalAgent = ctx.originalGlobalAgent;
it('should use a default socket prefix if none given', function(done) {
var socketMonitor = new SocketsMonitor({}, null, 1000);
expect(socketMonitor.prefix).to.equal('socket');
done();
});
});
describe('constructor', function() {
it('should use given socket prefix', function(done) {
var socketMonitor = new SocketsMonitor({}, 'prefix', 1000);
expect(socketMonitor.prefix).to.equal('prefix');
done();
});
it('should start monitor and report open files data & sockets info', function (done) {
http.globalAgent.sockets = [{id: 1}];
http.globalAgent.requests = [{id: 1}, {id: 2}];
it('should use a default socket prefix if none given', function(done) {
var socketMonitor = new SocketsMonitor({}, null, 1000);
expect(socketMonitor.prefix).to.equal('socket');
done();
});
});
var numSockets = http.globalAgent.sockets.length;
var numRequests = http.globalAgent.requests.length;
var ticks = 2;
var interval = 50;
var custom = monitor.createMonitor({interval: interval, prefix: 'git'});
var stub = sinon.stub(custom, 'gauge');
var clock = sinon.useFakeTimers();
sinon.stub(child, 'exec').yields(null, '10');
it('should start monitor and report open files data & sockets info', function (done) {
http.globalAgent.sockets = [{id: 1}];
http.globalAgent.requests = [{id: 1}, {id: 2}];
// Start the monitor and push the clock forward a few ticks...
custom.startSocketsMonitor();
clock.tick(ticks * interval + 1);
var numSockets = http.globalAgent.sockets.length;
var numRequests = http.globalAgent.requests.length;
var ticks = 2;
var interval = 50;
var custom = monitor.createMonitor({interval: interval, prefix: 'git'});
var stub = sinon.stub(custom, 'gauge');
var clock = sinon.useFakeTimers();
sinon.stub(child, 'exec').yields(null, '10');
// Every tick it should make one call every socket, every request, and an
// additional call for the number of open files.
expect(stub.callCount).to.equal(ticks * (numSockets + numRequests + 1));
expect(stub.calledWith(
sinon.match.string,
sinon.match.number,
sinon.match.number,
sinon.match.array)).to.equal(true);
// Start the monitor and push the clock forward a few ticks...
custom.startSocketsMonitor();
clock.tick(ticks * interval + 1);
child.exec.restore();
clock.restore();
done();
});
// Every tick it should make one call every socket, every request, and an
// additional call for the number of open files.
expect(stub.callCount).to.equal(ticks * (numSockets + numRequests + 1));
expect(stub.calledWith(
sinon.match.string,
sinon.match.number,
sinon.match.number,
sinon.match.array)).to.equal(true);
it('should gracefully handle errors in child.exec', function (done) {
http.globalAgent.sockets = [{id: 1}, {id: 2}, {id: 3}];
http.globalAgent.requests = [{id: 4}, {id: 5}];
child.exec.restore();
clock.restore();
done();
});
var numSockets = http.globalAgent.sockets.length;
var numRequests = http.globalAgent.requests.length;
var ticks = 2;
var interval = 50;
var custom = monitor.createMonitor({interval: interval, prefix: 'git'});
var stub = sinon.stub(custom, 'gauge');
var clock = sinon.useFakeTimers();
sinon.stub(child, 'exec').yields(new Error('Error'));
it('should gracefully handle errors in child.exec', function (done) {
http.globalAgent.sockets = [{id: 1}, {id: 2}, {id: 3}];
http.globalAgent.requests = [{id: 4}, {id: 5}];
custom.startSocketsMonitor();
clock.tick(ticks * interval + 1);
var numSockets = http.globalAgent.sockets.length;
var numRequests = http.globalAgent.requests.length;
var ticks = 2;
var interval = 50;
var custom = monitor.createMonitor({interval: interval, prefix: 'git'});
var stub = sinon.stub(custom, 'gauge');
var clock = sinon.useFakeTimers();
sinon.stub(child, 'exec').yields(new Error('Error'));
// This should not make gauge call for open files
expect(stub.callCount).to.equal(ticks * (numSockets + numRequests));
custom.startSocketsMonitor();
clock.tick(ticks * interval + 1);
// This should not make gauge call for open files
expect(stub.callCount).to.equal(ticks * (numSockets + numRequests));
child.exec.restore();
clock.restore();
done();
});
}); // end 'sockets-monitor'
}); // end 'monitor-dog'
child.exec.restore();
clock.restore();
done();
});
}); // end 'SocketsMonitor'

@@ -16,70 +16,109 @@ 'use strict';

require('loadenv')('monitor-dog');
var monitor = require('../index.js');
var dogstatsd = require('./fixtures/dogstatsd');
var Timer = require('../lib/timer.js');
describe('monitor-dog', function() {
describe('timer', function() {
beforeEach(function (done) {
dogstatsd.stubAll();
describe('Timer', function() {
describe('interface', function () {
it('should expose a `start` method', function (done) {
expect(Timer.prototype.start).to.be.a.function();
done();
});
afterEach(function (done) {
dogstatsd.restoreAll();
it('should expose a `stop` method', function (done) {
expect(Timer.prototype.stop).to.be.a.function();
done();
});
}); // end 'interface'
it('should start the timer by default', function (done) {
var timer = monitor.timer('timer');
expect(timer.startDate).to.exist();
describe('constructor', function() {
it('should start the timer', function(done) {
sinon.spy(Timer.prototype, 'start');
var t = new Timer(function() {});
expect(Timer.prototype.start.calledOnce).to.be.true();
Timer.prototype.start.restore();
done();
});
it('should not start the timer if instructed to not do so', function (done) {
var timer = monitor.timer('timer', false);
expect(timer.startDate).to.not.exist();
it('should start the timer when explicitly told to do so', function(done) {
sinon.spy(Timer.prototype, 'start');
var t = new Timer(function() {}, true);
expect(Timer.prototype.start.calledOnce).to.be.true();
Timer.prototype.start.restore();
done();
});
it('should call client histogram method with correct name when stopped', function (done) {
var timerName = 'timer';
monitor.client.histogram.restore();
sinon.stub(monitor.client, 'histogram', function (name, duration) {
expect(name).to.equal(monitor.prefix + '.' + timerName);
done();
});
var timer = monitor.timer(timerName);
timer.stop();
it('should not start the timer when instructed', function(done) {
sinon.spy(Timer.prototype, 'start');
var t = new Timer(function() {}, false);
expect(Timer.prototype.start.callCount).to.equal(0);
Timer.prototype.start.restore();
done();
});
}); // end 'constructor'
it('should report a realistic duration when stopped', function (done) {
var duration = 60;
var timer = monitor.timer('timer');
sinon.stub(timer, 'callback', function (duration) {
expect(duration).about(duration, 15);
done();
});
setTimeout(function () {
timer.stop();
}, duration);
describe('start', function() {
var clock;
var timer;
beforeEach(function (done) {
clock = sinon.useFakeTimers();
timer = new Timer(function() {}, false);
done();
});
it('should not attempt to start a timer multiple times', function (done) {
var timer = monitor.timer('timer', false);
afterEach(function (done) {
clock.restore();
done();
});
it('should set the start date', function(done) {
expect(timer.startDate).to.be.null();
timer.start();
var originalDate = timer.startDate;
expect(timer.startDate).to.not.be.null();
done();
});
it('should not set the date if called multiple times', function(done) {
timer.start();
expect(timer.startDate).to.equal(originalDate);
var date = timer.startDate;
clock.tick(3600);
timer.start();
timer.start();
timer.start();
expect(timer.startDate).to.equal(date);
done();
});
}); // end 'start'
it('should not execute the callback the timer is stopped before being started', function (done) {
var timer = monitor.timer('timer', false);
sinon.stub(timer, 'callback');
describe('stop', function() {
var clock;
var timer;
beforeEach(function (done) {
clock = sinon.useFakeTimers();
timer = new Timer(function() {}, false);
sinon.spy(timer, 'callback');
done();
});
afterEach(function (done) {
clock.restore();
done();
});
it('should not execute the callback if not started', function(done) {
timer.stop();
expect(timer.callback.callCount).to.equal(0);
timer.callback.restore();
done();
});
}); // end 'timer'
}); // end 'monitor-dog'
it('should execute the callback with the duration', function(done) {
var duration = 13371;
timer.start();
clock.tick(duration);
timer.stop();
expect(timer.callback.calledOnce).to.be.true();
expect(timer.callback.calledWith(duration)).to.be.true();
done();
});
}); // end 'stop'
}); // end 'Timer'
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