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

@akeating-redhat/fh-component-metrics

Package Overview
Dependencies
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@akeating-redhat/fh-component-metrics - npm Package Compare versions

Comparing version 2.3.0 to 2.7.0

lib/clients/base.js

2

Gruntfile.js

@@ -6,3 +6,3 @@ module.exports = function(grunt) {

_test_runner: '_mocha',
_unit_args: '-A -u exports -t 10000 ./test/unit',
_unit_args: '-A -u exports -t 10000 ./test/unit/test*.js',

@@ -9,0 +9,0 @@ unit: '<%= _test_runner %> <%= _unit_args %>',

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

var InfluxUdp = require('./lib/sender');
var MetricsClients = require('./lib/clients');

@@ -7,15 +7,16 @@ module.exports = function metrics(conf) {

var confEnabled = config.enabled();
var influxclient = new InfluxUdp(config.getConfig());
var counter = require('./lib/counter')(influxclient);
var clients = new MetricsClients(config.getConfig());
var counter = require('./lib/counter')(clients);
var nothing = function() {};
return {
"cpu": confEnabled ? require('./lib/cpu')(influxclient) : nothing,
"memory": confEnabled ? require('./lib/memory')(influxclient) : nothing,
"gauge": confEnabled ? require('./lib/gauge')(influxclient) : nothing,
"cpu": confEnabled ? require('./lib/cpu')(clients) : nothing,
"memory": confEnabled ? require('./lib/memory')(clients) : nothing,
"gauge": confEnabled ? require('./lib/gauge')(clients) : nothing,
"inc": confEnabled ? counter.inc : nothing,
"dec": confEnabled ? counter.dec : nothing
"dec": confEnabled ? counter.dec : nothing,
"timer": confEnabled ? require('./lib/timer')(clients) : nothing
};
};
module.exports.timingMiddleware = require('./lib/timingMiddleware');
module.exports.timingMiddleware = require('./lib/timingMiddleware');
var util = require('util');
module.exports = function(config) {
var BASE_ERROR = "invalid config expected %s";
var backends = [];
if (config.backends) {
backends = config.backends;
} else if (config.host) {
//keep it backward compatible
backends = [{type: 'influxdb', host: config.host, port: config.port}];
}
return {
"getConfig": function() {
return config;
return backends;
},

@@ -21,5 +28,5 @@ "getHost": function() {

"enabled": function() {
return config.enabled === true || config.enabled === 'true';
return (config.enabled === true || config.enabled === 'true') && backends.length > 0;
}
};
};
var gauge = require('./gauge');
var types = require('./types');
module.exports = function(influxclient) {
module.exports = function(metricsClients) {
var g = gauge(influxclient);
var g = gauge(metricsClients, types.C);

@@ -7,0 +8,0 @@ return {

var fs = require('fs');
var os = require('os');
var types = require('./types');

@@ -10,2 +11,3 @@ // http://stackoverflow.com/a/7774034/2829381

}
var timeOfRead = Date.now();

@@ -16,9 +18,9 @@ var elems = data.toString().split(' ');

cb(undefined,utime + stime);
cb(undefined, utime + stime, timeOfRead);
});
};
var alreadySendingToKey = {};
var checkInterval = {};
module.exports = function(influxclient) {
module.exports = function(metricsClients) {

@@ -30,4 +32,12 @@ return function cpu(component, opts, cb) {

var cacheKey = key + seriesName + workerId;
if (opts.stop) {
if (checkInterval[cacheKey]) {
clearInterval(checkInterval[cacheKey]);
delete checkInterval[cacheKey];
}
return cb();
}
var usageFunc = opts.getUsage ? opts.getUsage : getUsage;
var handleError = function(err) {
/*eslint-disable no-console */
console.error("error getting cpu usage ",err);

@@ -39,12 +49,10 @@ if ('function' === typeof cb) {

if (alreadySendingToKey[cacheKey]) {
if (checkInterval[cacheKey]) {
cb('Already sending ' + seriesName + ' to ' + key);
} else {
alreadySendingToKey[cacheKey] = true;
var interval = opts.interval || 2000; // how often to poll
var period = opts.period || 1000; // period to measure
setInterval(function() {
usageFunc(function(err, startTime) {
checkInterval[cacheKey] = setInterval(function() {
usageFunc(function(err, startTime, startTimeOfRead) {
if (err) {

@@ -54,3 +62,3 @@ return handleError(err);

setTimeout(function() {
usageFunc(function(err,endTime) {
usageFunc(function(err, endTime, endTimeOfRead) {
if (err) {

@@ -60,4 +68,10 @@ return handleError(err);

var proctime = endTime - startTime;
var percentage = 100 * (proctime / 10000);
// The actual sample period may not match the configured period,
// particularly if the process is blocked for longer than the period.
// To ensure accurate results, calculate percentage cpu usage
// over time between both sample reads.
var secondsBetweenReads = (endTimeOfRead - startTimeOfRead) / 1000;
var percentage = 100 * (proctime / (10000 * secondsBetweenReads));
var point = {};

@@ -67,2 +81,3 @@ point[seriesName] = percentage;

var data = {};
data.type = types.G;
data.key = key;

@@ -74,4 +89,5 @@ data.tags = {

data.fields = point;
data.timestamp = Date.now();
influxclient.send(data);
metricsClients.send.call(metricsClients, data);
if ('function' === typeof cb) {

@@ -78,0 +94,0 @@ cb(null, data);

var os = require('os');
var types = require('./types');
module.exports = function(influxclient) {
module.exports = function(metricsClients, type) {
return function(key, tag, value, cb) {
var data = {};
//the type of the metric
data.type = type || types.G;
data.key = key;

@@ -12,3 +15,4 @@ data.tags = tag || {};

data.fields = {value: value};
influxclient.send(data);
data.timestamp = Date.now();
metricsClients.send.call(metricsClients, data);

@@ -15,0 +19,0 @@ if ('function' === typeof cb) {

var os = require('os');
var types = require('./types');
var alreadySendingToKey = {};
module.exports = function(influxclient) {
module.exports = function(metricsClients) {

@@ -29,2 +30,3 @@ function getHeap() {

var data = {};
data.type = types.G;
data.key = key;

@@ -36,3 +38,4 @@ data.tags = {

data.fields = getHeap();
influxclient.send(data);
data.timestamp = Date.now();
metricsClients.send.call(metricsClients, data);
if ('function' === typeof cb) {

@@ -39,0 +42,0 @@ cb(null, data);

var gauge = require('./gauge');
var InfluxUdp = require('./sender');
var types = require('./types');
var MetricsClients = require('./clients');
var _ = require('lodash');
module.exports = function(component, metrics_conf) {
return function(req, res, next) {
if (metrics_conf.enabled) {
var timeFunc = gauge(new InfluxUdp(metrics_conf));
var start = Date.now();
res._end = res.end;
res.end = function(data, encoding, callback) {
res._end(data, encoding, callback);
var timeTaken = Date.now() - start;
module.exports = function timingMiddlewareCreator(component, metrics_conf) {
var config = require('./config')(metrics_conf);
var metricsEnabled = config.enabled();
var clients = metricsEnabled ? new MetricsClients(config.getConfig()) : null;
var timeFunc = metricsEnabled ? gauge(clients, types.T) : null;
return function timingMiddleware(req, res, next) {
if (metricsEnabled) {
var start = process.hrtime();
res.on('finish', function timingMiddlewareFinishListener() {
var hrTime = process.hrtime(start);
var millisecondsTaken = (hrTime[0] * 1000) + (hrTime[1] / 1000000);
var route = req.permissionpath || req.route || req.path || req.url;

@@ -20,7 +24,8 @@ if (_.isObject(route)) {

if ('string' === typeof route) {
timeFunc(component + '_api_timing', {route: route}, timeTaken);
timeFunc(component + '_api_timing', {route: route}, millisecondsTaken);
} else {
/*eslint-disable no-console */
console.error("failed to determine route cannot gauge timing : fh-component-metrics");
}
};
});
return next();

@@ -27,0 +32,0 @@ } else {

{
"name": "@akeating-redhat/fh-component-metrics",
"version": "2.3.0",
"version": "2.7.0",
"description": "influx db metrics wrapper",

@@ -20,4 +20,5 @@ "main": "index.js",

"dependencies": {
"async": "2.0.1",
"lodash": "4.3.0"
"async": "2.1.5",
"debug": "^2.6.4",
"lodash": "4.17.4"
},

@@ -24,0 +25,0 @@ "devDependencies": {

@@ -14,3 +14,2 @@ # fh-component-metrics

# Usage Guide

@@ -42,4 +41,15 @@

3. To capture API time, you can add the timingMiddleware to an existing express app like this:
3. Send metrics data to multiple backends. By default, if you only need to send metrics data to an Influxdb backend, you can specify the configuration as the example above. But it also supports some other backends like Statsd and it can send the metrics data to multiple backends at the same time. To do that, you just need to change the configuration and replace the `host` and `port` value with an array called `backends`:
```
var fhComponentMetrics = require('fh-component-metrics');
var metricsConf = {enabled: true, backends:[{type: 'influxdb', host: '1.2.3.4', port: 2003}, {type: 'statsd', host: '1.2.3.4', port: 2004}];
var metrics = fhComponentMetrics(metricsConf);
//the metrics data will be sent to both the influxdb and statsd backend
```
At the moment, it supports Influxdb, Statsd and redis, so the valid options for the `type` field are `influxdb`, `statsd` and `redis`. See the next section for more details about the available options for each type.
4. To capture API time, you can add the timingMiddleware to an existing express app like this:
```

@@ -52,3 +62,3 @@ var fhComponentMetrics = require('fh-component-metrics');

4. It's better the add the metrics configuration into the component's configuation file. E.g.
5. It's better the add the metrics configuration into the component's configuation file. E.g.

@@ -65,2 +75,29 @@ ```

}
```
```
# Configuration Options for Each Backend Type
## Influxdb
* host: the host of the influxdb
* port: the port of the influxdb. It has to be a UDP port.
## Statsd
* host: the host of the statsd server
* port: the port of the statsd server. It has to be a UDP port.
* keyBuilder: a function that will allow override how the metric key is being built. If not provided, a default function will be provided. See [statsd.js](./lib/clients/statsd.js) for more details.
NOTE: each metric will be formatted as described in this [spec](https://github.com/b/statsd_spec) before sending to the server.
## Redis
* redisClient: an instance of https://github.com/NodeRedis/node_redis#rediscreateclient.
* recordsToKeep: how many records to keep in redis
* namespace: a prefix that will be added to each metric key
NOTE: each record will be added to a list in Redis. The key for the list is the metric name. Each record will is a stringified JSON object, with the follow fields:
* tags
* fields
* ts
var assert = require('assert');
var types = require('../../lib/types');
var influxmock = {
var clientsMock = {
send: function() {}
};
var counter = require('counter')(influxmock);
var counter = require('counter')(clientsMock);

@@ -12,2 +13,3 @@ exports.inc_should_send_plus_one = function(done) {

assert.ok(!err);
assert.ok(data.type, types.C);
assert.ok(data.hasOwnProperty('key'));

@@ -24,2 +26,3 @@ assert.ok(data.key, 'testKey');

assert.ok(!err);
assert.ok(data.type, types.C);
assert.ok(data.hasOwnProperty('key'));

@@ -26,0 +29,0 @@ assert.ok(data.key, 'testKey');

var assert = require('assert');
var proxyquire = require('proxyquire');
var os = require('os');
var sinon = require('sinon');
var mocks = {
'./lib/sender': function() {
'./lib/clients': function() {
this.send = function() {};

@@ -11,3 +12,4 @@ }

var metrics = proxyquire('index.js', mocks)({enabled: true});
var metrics = proxyquire('index.js', mocks)({enabled: true, host: '127.0.0.1'});
var component = 'testComponent';

@@ -20,9 +22,13 @@ var customGetUsage = function(cb) {

cb(undefined,utime + stime);
cb(undefined, utime + stime, Date.now());
};
exports.afterEach = function(done) {
metrics.cpu(component, {stop: true}, done);
};
exports.cpu_should_send_valid_object = function(finish) {
var called = false;
metrics.cpu('testComponent', {interval: 10, period: 5,"getUsage": customGetUsage}, function(err, data) {
metrics.cpu(component, {interval: 10, period: 5,"getUsage": customGetUsage}, function(err, data) {
assert.ok(!err);

@@ -45,6 +51,34 @@ assert.ok(data.hasOwnProperty('key'));

exports.cpu_should_not_send_twice_to_same_series = function(finish) {
metrics.cpu('testComponent', {interval: 10, period: 5, getUsage:customGetUsage}, function(err) {
assert.ok(err);
finish();
metrics.cpu(component, {interval: 10, period: 5,"getUsage": customGetUsage}, function(err, data) {
assert.ok(!err, err);
metrics.cpu(component, {interval: 10, period: 5, getUsage:customGetUsage}, function(err) {
assert.ok(err);
finish();
});
});
};
exports.cpu_should_calculate_percentage_usage = function(finish) {
var usageStub = sinon.stub();
// 6% usage over 1 second
usageStub.onCall(0).callsArgWithAsync(0, null, 0, 0);
usageStub.onCall(1).callsArgWithAsync(0, null, 6, 1000);
// the interval doens't matter here as we're mocking the read time above
metrics.cpu(component, {interval: 10, period: 5,"getUsage": usageStub}, function(err, data) {
assert.ok(!err, err);
assert.equal(data.fields.cpuUsed, 0.06); // 6%
// 3% usage over 2 seconds
usageStub.onCall(2).callsArgWithAsync(0, null, 0, 0);
usageStub.onCall(3).callsArgWithAsync(0, null, 6, 2000);
metrics.cpu(component, {stop: true}, function(err) {
assert.ok(!err, err);
metrics.cpu(component, {interval: 10, period: 5,"getUsage": usageStub}, function(err, data) {
assert.ok(!err, err);
assert.equal(data.fields.cpuUsed, 0.03); // 3%
return finish();
});
})
});
};
var assert = require('assert');
var types = require('../../lib/types');
var influxmock = {
var clientsMock = {
send: function() {}
};
var timed = require('gauge')(influxmock);
var timed = require('gauge')(clientsMock, types.G);

@@ -12,2 +13,3 @@ exports.timed_should_send_valid_object = function(done) {

assert.ok(!err);
assert.equal(data.type, types.G);
assert.ok(data.hasOwnProperty('key'));

@@ -14,0 +16,0 @@ assert.ok(data.key, 'testKey');

@@ -62,3 +62,3 @@ var sinon = require('sinon');

exports.test_metricsEnabled = function(done) {
var m = metrics({enabled: true});
var m = metrics({enabled: true, host: 'localhost'});
checkMetric(m, true);

@@ -65,0 +65,0 @@ done();

@@ -6,3 +6,3 @@ var assert = require('assert');

var mocks = {
'./lib/sender': function() {
'./lib/clients': function() {
this.send = function() {};

@@ -12,3 +12,3 @@ }

var metrics = proxyquire('index.js', mocks)({enabled: true});
var metrics = proxyquire('index.js', mocks)({enabled: true, host: '127.0.0.1'});

@@ -15,0 +15,0 @@ exports.mem_should_send_valid_object = function(finish) {

@@ -27,3 +27,3 @@ var assert = require('assert');

},
'./sender': function() {
'./clients': function() {

@@ -53,3 +53,3 @@ }

},
'./sender': function() {
'./clients': function() {

@@ -82,3 +82,3 @@ }

},
'./sender': function() {
'./clients': function() {

@@ -85,0 +85,0 @@ }

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