monitor-dog
Advanced tools
Comparing version 1.3.0 to 1.4.0
@@ -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' |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
53618
20
1418
5