chpr-metrics
Advanced tools
Comparing version 1.0.0 to 1.1.0
70
index.js
'use strict'; | ||
const StatsD = require('node-statsd'); | ||
const StatsDClient = require('node-statsd'); | ||
const config = { | ||
host: process.env.METRICS_HOST || null, | ||
port: process.env.METRICS_PORT || null, | ||
prefix: process.env.METRICS_PREFIX || '', | ||
suffix: process.env.METRICS_SUFFIX || '', | ||
cacheDns: process.env.METRICS_CACHE_DNS === 'true' | ||
}; | ||
/** | ||
* Builds the configuration to pass to the StatsD client from the environment names decided previously. | ||
* | ||
* @param {Object} options A key - value that respect the contract stated in the Readme for defining a single | ||
* destination with multiple environment variables | ||
* | ||
* @returns {Object} an object suitable to pass as options to the StatsD client constructor | ||
*/ | ||
function buildConfig(options) { | ||
return { | ||
host: options.METRICS_HOST || null, | ||
port: options.METRICS_PORT || null, | ||
prefix: options.METRICS_PREFIX || '', | ||
suffix: options.METRICS_SUFFIX || '', | ||
cacheDns: options.METRICS_CACHE_DNS === 'true' | ||
}; | ||
} | ||
module.exports = new StatsD(config); | ||
const configs = []; | ||
if (process.env.METRICS_HOST) { | ||
configs.push(buildConfig(process.env)); | ||
} | ||
if (process.env.METRICS_DESTINATIONS) { | ||
for (const destination of JSON.parse(process.env.METRICS_DESTINATIONS)) { | ||
configs.push(buildConfig(destination)); | ||
} | ||
} | ||
if (configs.length === 0) { | ||
configs.push(buildConfig({})); | ||
} | ||
if (configs.length === 1) { | ||
module.exports = new StatsDClient(configs[0]); | ||
} else { | ||
/** | ||
* This class is a proxy to several StatsD clients. It has the same methods, and their implementation | ||
* consists in calling the method on each of the clients. | ||
* | ||
* @param {Array<StatsDClient>} clients A list of StatsD client to proxy | ||
* @constructor | ||
*/ | ||
const StatsDClientsProxy = function StatsDClientsProxy(clients) { | ||
this.clients = clients; | ||
}; | ||
/** | ||
* Iterate on the StatsDClient.prototype to recreate all the methods on the StatsDClientsProxy class | ||
*/ | ||
for (const publicMethodName in StatsDClient.prototype) { | ||
if (StatsDClient.prototype.hasOwnProperty(publicMethodName)) { | ||
StatsDClientsProxy.prototype[publicMethodName] = function methodImplementation() { | ||
for (const client of this.clients) { | ||
client[publicMethodName].apply(client, arguments); | ||
} | ||
}; | ||
} | ||
} | ||
const clients = configs.map(config => new StatsDClient(config)); | ||
module.exports = new StatsDClientsProxy(clients); | ||
} |
{ | ||
"name": "chpr-metrics", | ||
"version": "1.0.0", | ||
"version": "1.1.0", | ||
"description": "Chauffeur Privé's statsd configuration", | ||
@@ -24,9 +24,9 @@ "repository": { | ||
"chai": "3.5.0", | ||
"co-mocha": "1.1.2", | ||
"co-mocha": "1.1.3", | ||
"eslint-config-cp": "github:transcovo/eslint-config-cp#1.1.0", | ||
"istanbul": "0.4.3", | ||
"mocha": "2.4.5", | ||
"istanbul": "0.4.5", | ||
"mocha": "3.2.0", | ||
"mocha-lcov-reporter": "1.2.0", | ||
"coveralls": "2.11.9", | ||
"rewire": "2.5.1" | ||
"coveralls": "2.11.15", | ||
"rewire": "2.5.2" | ||
}, | ||
@@ -33,0 +33,0 @@ "dependencies": { |
@@ -15,2 +15,4 @@ This utility library implements our standard statsd configuration | ||
This simple configuration allows you to send metrics to a single statds server | ||
* METRICS_HOST | ||
@@ -22,2 +24,24 @@ * METRICS_PORT | ||
## Advanced configuration | ||
If you need to send metrics to several destinations, you can use the METRICS_DESTINATIONS | ||
variable, which allows you to specify a list of destinations as a JSON array: | ||
Complete example: | ||
[{ | ||
"METRICS_HOST": "host1.yourstats.com", | ||
"METRICS_PORT": "1234", | ||
"METRICS_PREFIX": "prefix1.", | ||
"METRICS_SUFFIX": ".suffix1" | ||
}, { | ||
"METRICS_HOST": "your-other-host.com", | ||
"METRICS_PORT": "44444", | ||
"METRICS_PREFIX": "anotherPrefix.", | ||
"METRICS_SUFFIX": ".anotherSuffix" | ||
}] | ||
If you use this in combination with the individual configuration variables listed | ||
in the previous sections, it will send metrics to all directions. | ||
## Use | ||
@@ -24,0 +48,0 @@ |
@@ -8,31 +8,108 @@ 'use strict'; | ||
describe('index.js', () => { | ||
it('should not crash if configuration variables are not set (dev)', () => { | ||
const oldEnv = process.env; | ||
process.env = {}; | ||
const metrics = rewire('../index'); | ||
process.env = oldEnv; | ||
metrics.increment('hello'); | ||
let oldEnv; | ||
beforeEach(() => { | ||
oldEnv = process.env; | ||
}); | ||
it('should send metrics on UDP port', done => { | ||
const oldEnv = process.env; | ||
process.env = { | ||
METRICS_HOST: 'localhost', | ||
METRICS_PORT: '18125', | ||
METRICS_PREFIX: 'prefix.', | ||
METRICS_SUFFIX: '.suffix' | ||
}; | ||
const metrics = rewire('../index'); | ||
afterEach(() => { | ||
process.env = oldEnv; | ||
}); | ||
const server = dgram.createSocket('udp4'); | ||
server.on('error', () => expect.fail()); | ||
server.on('message', msg => { | ||
expect(msg.toString()).to.be.eql('prefix.hello.suffix:1|c'); | ||
done(); | ||
describe('when configuration variables are not set', () => { | ||
it('should not crash', () => { | ||
process.env = {}; | ||
const metrics = rewire('../index'); | ||
metrics.increment('hello'); | ||
}); | ||
server.bind(18125); | ||
}); | ||
metrics.increment('hello'); | ||
describe('when configuration is specified with individual variables', () => { | ||
it('should send metrics on UDP port', function* it() { | ||
process.env = { | ||
METRICS_HOST: 'localhost', | ||
METRICS_PORT: '18125', | ||
METRICS_PREFIX: 'prefix.', | ||
METRICS_SUFFIX: '.suffix' | ||
}; | ||
const metrics = rewire('../index'); | ||
const server = dgram.createSocket('udp4'); | ||
const listening = new Promise(resolve => { | ||
server.on('listening', resolve); | ||
}); | ||
server.bind(18125); | ||
yield listening; | ||
const done = new Promise((resolve, reject) => { | ||
server.on('error', () => reject); | ||
server.on('message', msg => { | ||
expect(msg.toString()).to.be.eql('prefix.hello.suffix:1|c'); | ||
resolve(); | ||
}); | ||
}); | ||
metrics.increment('hello'); | ||
yield done; | ||
}); | ||
}); | ||
describe('when configuration is specified with a single METRICS_DESTINATIONS variable', () => { | ||
it('should send metrics on UDP port for both servers', function* it() { | ||
process.env = { | ||
METRICS_DESTINATIONS: JSON.stringify([{ | ||
METRICS_HOST: 'localhost', | ||
METRICS_PORT: '18127', | ||
METRICS_PREFIX: 'prefix1.', | ||
METRICS_SUFFIX: '.suffix1' | ||
}, { | ||
METRICS_HOST: 'localhost', | ||
METRICS_PORT: '18128', | ||
METRICS_PREFIX: 'prefix2.', | ||
METRICS_SUFFIX: '.suffix2' | ||
}]) | ||
}; | ||
const metrics = rewire('../index'); | ||
const server1 = dgram.createSocket('udp4'); | ||
const server2 = dgram.createSocket('udp4'); | ||
const listening = [ | ||
new Promise(resolve => { | ||
server1.on('listening', resolve); | ||
}), | ||
new Promise(resolve => { | ||
server2.on('listening', resolve); | ||
}) | ||
]; | ||
server1.bind(18127); | ||
server2.bind(18128); | ||
yield listening; | ||
const done = [ | ||
new Promise((resolve, reject) => { | ||
server1.on('error', reject); | ||
server1.on('message', msg => { | ||
expect(msg.toString()).to.be.eql('prefix1.helloTiming.suffix1:42|ms'); | ||
resolve(); | ||
}); | ||
}), | ||
new Promise((resolve, reject) => { | ||
server2.on('error', reject); | ||
server2.on('message', msg => { | ||
expect(msg.toString()).to.be.eql('prefix2.helloTiming.suffix2:42|ms'); | ||
resolve(); | ||
}); | ||
}) | ||
]; | ||
metrics.timing('helloTiming', 42); | ||
yield done; | ||
}); | ||
}); | ||
}); |
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
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
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
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 4 instances in 1 package
8898
154
60
9