Socket
Socket
Sign inDemoInstall

hot-shots

Package Overview
Dependencies
Maintainers
1
Versions
90
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hot-shots - npm Package Compare versions

Comparing version 5.9.2 to 6.0.0

.eslintrc.js

19

CHANGES.md
CHANGELOG
=========
## 6.0.0 (2018-12-15)
@bdeitte Major upgrade to the codebase to be more modern,
overhaul tests, and many small tweaks. Most of this is internal to
the project, but there are a few changes to note for everyone:
* Now requires Node 6 or above
* Update close() to handle errors better, not doubling up in error
messages and not leaving uncaught errors
Everything else done here should be internal facing. Those changes
include:
* Use "lebab" to ES6-ify the project
* Switch from jshint and eslint and make syntax updates based on this
* Remove a lot of duplication in tests and many small fixups in tests
* Start using Mocha 4
* Stop using index.js for testing
* Start using the code coverage report as part of the build
* Remove the ignoring of errors on close of tests, and tear down tests in general better
* Stop using "new Buffer", that is deprecated, and use Buffer.from() instead
## 5.9.2 (2018-11-10)

@@ -5,0 +24,0 @@ * @stieg Add mockBuffer to types

2

index.js

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

module.exports = require('./lib/statsd');
module.exports = require('./lib/statsd');

@@ -1,11 +0,15 @@

"use strict";
const fs = require('fs');
var fs = require('fs');
/**
* Replace any characters that can't be sent on with an underscore
*/
function sanitizeTags(value, telegraf) {
var blacklist = telegraf ? /:|\|/g : /:|\||@|,/g;
const blacklist = telegraf ? /:|\|/g : /:|\||@|,/g;
// Replace reserved chars with underscores.
return (value + "").replace(blacklist, "_");
return value.replace(blacklist, '_');
}
/**
* Format tags properly before sending on
*/
function formatTags(tags, telegraf) {

@@ -16,4 +20,4 @@ if (Array.isArray(tags)) {

} else {
return Object.keys(tags).map(function (key) {
return sanitizeTags(key, telegraf) + ":" + sanitizeTags(tags[key], telegraf);
return Object.keys(tags).map(key => {
return `${sanitizeTags(key, telegraf)}:${sanitizeTags(tags[key], telegraf)}`;
});

@@ -28,6 +32,6 @@ }

function overrideTags (parent, child, telegraf) {
var childCopy = {};
var toAppend = [];
formatTags(child, telegraf).forEach(function (tag) {
var idx = typeof tag === 'string' ? tag.indexOf(':') : -1;
const childCopy = {};
const toAppend = [];
formatTags(child, telegraf).forEach(tag => {
const idx = typeof tag === 'string' ? tag.indexOf(':') : -1;
if (idx < 1) { // Not found or first character

@@ -39,17 +43,17 @@ toAppend.push(tag);

});
var result = parent.map(function (tag) {
var idx = typeof tag === 'string' ? tag.indexOf(':') : -1;
const result = parent.map(tag => {
const idx = typeof tag === 'string' ? tag.indexOf(':') : -1;
if (idx < 1) { // Not found or first character
return tag;
}
var key = tag.substring(0, idx);
const key = tag.substring(0, idx);
if (childCopy.hasOwnProperty(key)) {
var value = childCopy[key];
const value = childCopy[key];
delete childCopy[key];
return key + ':' + value;
return `${key}:${value}`;
}
return tag;
});
Object.keys(childCopy).forEach(function (key) {
result.push(key + ':' + childCopy[key]);
Object.keys(childCopy).forEach(key => {
result.push(`${key}:${childCopy[key]}`);
});

@@ -59,5 +63,7 @@ return result.concat(toAppend);

// Formats a date for use with DataDog
/**
* Formats a date for use with DataDog
*/
function formatDate(date) {
var timestamp;
let timestamp;
if (date instanceof Date) {

@@ -73,23 +79,27 @@ // Datadog expects seconds.

// Converts int to a string IP
/**
* Converts int to a string IP
*/
function intToIP(int) {
var part1 = int & 255;
var part2 = ((int >> 8) & 255);
var part3 = ((int >> 16) & 255);
var part4 = ((int >> 24) & 255);
const part1 = int & 255;
const part2 = ((int >> 8) & 255);
const part3 = ((int >> 16) & 255);
const part4 = ((int >> 24) & 255);
return part4 + "." + part3 + "." + part2 + "." + part1;
return `${part4}.${part3}.${part2}.${part1}`;
}
// Returns the system default interface on Linux
/**
* Returns the system default interface on Linux
*/
function getDefaultRoute() {
try {
var fileContents = fs.readFileSync('/proc/net/route', 'utf8');
var routes = fileContents.split('\n');
for (var routeIdx in routes) {
var fields = routes[routeIdx].trim().split('\t');
const fileContents = fs.readFileSync('/proc/net/route', 'utf8'); // eslint-disable-line no-sync
const routes = fileContents.split('\n');
for (const routeIdx in routes) {
const fields = routes[routeIdx].trim().split('\t');
if (fields[1] === '00000000') {
var address = fields[2];
const address = fields[2];
// Convert to little endian by splitting every 2 digits and reversing that list
var littleEndianAddress = address.match(/.{2}/g).reverse().join("");
const littleEndianAddress = address.match(/.{2}/g).reverse().join('');
return intToIP(parseInt(littleEndianAddress, 16));

@@ -96,0 +106,0 @@ }

@@ -1,32 +0,16 @@

'use strict';
const dgram = require('dgram'),
util = require('util'),
dns = require('dns'),
net = require('net'),
helpers = require('./helpers'),
applyStatsFns = require('./statsFunctions');
var dgram = require('dgram'),
util = require('util'),
dns = require('dns'),
net = require('net'),
helpers = require('./helpers'),
applyStatsFns = require('./statsFunctions');
/**
* The UDP Client for StatsD
* @param options
* @option host {String} The host to connect to default: localhost
* @option port {String|Integer} The port to connect to default: 8125
* @option prefix {String} An optional prefix to assign to each stat name sent
* @option suffix {String} An optional suffix to assign to each stat name sent
* @option globalize {boolean} An optional boolean to add 'statsd' as an object in the global namespace
* @option cacheDns {boolean} An optional option to only lookup the hostname -> ip address once
* @option mock {boolean} An optional boolean indicating this Client is a mock object, no stats are sent.
* @option globalTags {Array=} Optional tags that will be added to every metric
* @option errorHandler {Function=} Optional function to handle errors when callback is not provided
* @maxBufferSize {Number} An optional value for aggregating metrics to send, mainly for performance improvement
* @bufferFlushInterval {Number} the time out value to flush out buffer if not
* @option sampleRate {Float} Global Sampling rate, default: 1 (No sampling)
* @option useDefaultRoute {boolean} An optional boolean to use the default route on Linux. Useful for containers
* The Client for StatsD
* @constructor
*/
var Client = function (host, port, prefix, suffix, globalize, cacheDns, mock,
const Client = function (host, port, prefix, suffix, globalize, cacheDns, mock,
globalTags, maxBufferSize, bufferFlushInterval, telegraf, sampleRate, protocol) {
var options = host || {},
self = this;
let options = host || {};
const self = this;

@@ -51,5 +35,5 @@ if (arguments.length > 1 || typeof(host) === 'string') {

var createSocket = function createSocket(instance, args) {
var socket;
var errMessage;
const createSocket = function createSocket(instance, args) {
let socket;
let errMessage;

@@ -61,3 +45,3 @@ if (args.protocol === 'tcp') {

} catch (e) {
errMessage = 'Could not establish connection to ' + args.host + ':' + args.port;
errMessage = `Could not establish connection to ${args.host}:${args.port}`;
if (instance.errorHandler) {

@@ -114,3 +98,3 @@ instance.errorHandler(new Error(errMessage));

} else if (options.cacheDns === true) {
dns.lookup(options.host, function (err, address, family) {
dns.lookup(options.host, (err, address) => {
if (err === null) {

@@ -133,5 +117,5 @@ self.host = address;

if (options.useDefaultRoute) {
var defaultRoute = helpers.getDefaultRoute();
const defaultRoute = helpers.getDefaultRoute();
if (defaultRoute) {
console.log('Got ' + defaultRoute + ' for the system\'s default route');
console.log(`Got ${defaultRoute} for the system's default route`);
this.host = defaultRoute;

@@ -161,6 +145,6 @@ }

Client.prototype.sendAll = function (stat, value, type, sampleRate, tags, callback) {
var completed = 0,
calledback = false,
sentBytes = 0,
self = this;
let completed = 0;
let calledback = false;
let sentBytes = 0;
const self = this;

@@ -210,3 +194,3 @@ if (sampleRate && typeof sampleRate !== 'number') {

if (Array.isArray(stat)) {
stat.forEach(function (item) {
stat.forEach(item => {
self.sendStat(item, value, type, sampleRate, tags, onSend);

@@ -229,3 +213,3 @@ });

Client.prototype.sendStat = function (stat, value, type, sampleRate, tags, callback) {
var message = this.prefix + stat + this.suffix + ':' + value + '|' + type;
let message = `${this.prefix + stat + this.suffix}:${value}|${type}`;

@@ -235,3 +219,3 @@ sampleRate = sampleRate || this.sampleRate;

if (Math.random() < sampleRate) {
message += '|@' + sampleRate;
message += `|@${sampleRate}`;
} else {

@@ -252,3 +236,3 @@ // don't want to send if we don't meet the sample ratio

Client.prototype.send = function (message, tags, callback) {
var mergedTags = this.globalTags;
let mergedTags = this.globalTags;
if (tags && typeof tags === 'object') {

@@ -260,5 +244,5 @@ mergedTags = helpers.overrideTags(mergedTags, tags, this.telegraf);

message = message.split(':');
message = message[0] + ',' + mergedTags.join(',').replace(/:/g, '=') + ':' + message.slice(1).join(':');
message = `${message[0]},${mergedTags.join(',').replace(/:/g, '=')}:${message.slice(1).join(':')}`;
} else {
message += '|#' + mergedTags.join(',');
message += `|#${mergedTags.join(',')}`;
}

@@ -350,3 +334,3 @@ }

var buf = new Buffer(message);
const buf = Buffer.from(message);
try {

@@ -359,3 +343,3 @@ if (this.protocol === 'tcp') {

} catch (err) {
var errMessage = 'Error sending hot-shots message: ' + err;
const errMessage = `Error sending hot-shots message: ${err}`;
if (callback) {

@@ -388,6 +372,37 @@ callback(new Error(errMessage));

// error function to use in callback and catch below
let handledError = false;
const handleErr = (err) => {
const errMessage = `Error closing hot-shots socket: ${err}`;
if (handledError) {
console.log(errMessage);
}
else {
// The combination of catch and error can lead to some errors
// showing up twice. So we just show one of the errors that occur
// on close.
handledError = true;
if (callback) {
callback(new Error(errMessage));
} else if (this.errorHandler) {
this.errorHandler(new Error(errMessage));
} else {
console.log(errMessage);
}
}
};
if (this.errorHandler) {
this.socket.removeListener('error', this.errorHandler);
}
// handle error and close events
this.socket.on('error', handleErr);
if (callback) {
// use the close event rather than adding a callback to close()
// because that API is not available in older Node versions
this.socket.on('close', callback);
this.socket.on('close', err => {
if (! handledError && callback) {
callback(err);
}
});
}

@@ -402,14 +417,7 @@

} catch (err) {
var errMessage = 'Error closing hot-shots socket: ' + err;
if (callback) {
callback(new Error(errMessage));
} else if (this.errorHandler) {
this.errorHandler(new Error(errMessage));
} else {
console.log(errMessage);
}
handleErr(err);
}
};
var ChildClient = function (parent, options) {
const ChildClient = function (parent, options) {
options = options || {};

@@ -416,0 +424,0 @@ Client.call(this, {

@@ -1,6 +0,9 @@

"use strict";
const helpers = require('./helpers');
var helpers = require('./helpers');
/**
* Separated out of statsd.js for clarity, these are the timing and other stats functions that are what are called the most
* when using hot-shots
*/
function applyStatsFns (Client) {
function applyStatsFns (Client) {
/**

@@ -27,14 +30,14 @@ * Represents the timing stat

Client.prototype.timer = function (func, stat, sampleRate, tags, callback) {
var _this = this;
const _this = this;
return function () {
var start = process.hrtime();
return (...args) => {
const start = process.hrtime();
try {
return func.apply(null, arguments);
return func(...args);
} finally {
// get duration in milliseconds
var durationComponents = process.hrtime(start);
var seconds = durationComponents[0];
var nanoseconds = durationComponents[1];
var duration = seconds * 1000 + nanoseconds / 1E6;
const durationComponents = process.hrtime(start);
const seconds = durationComponents[0];
const nanoseconds = durationComponents[1];
const duration = (seconds * 1000) + (nanoseconds / 1E6);

@@ -65,7 +68,7 @@ _this.timing(

Client.prototype.asyncTimer = function (func, stat, sampleRate, tags, callback) {
var self = this;
return function() {
var end = hrtimer();
var p = func.apply(null, arguments);
var recordStat = function() { self.timing(stat, end(), sampleRate, tags, callback); };
const self = this;
return (...args) => {
const end = hrtimer();
const p = func(...args);
const recordStat = () => { self.timing(stat, end(), sampleRate, tags, callback); };
p.then(recordStat, recordStat);

@@ -76,10 +79,13 @@ return p;

/**
* High-resolution timer
*/
function hrtimer() {
var start = process.hrtime();
const start = process.hrtime();
return function () {
var durationComponents = process.hrtime(start);
var seconds = durationComponents[0];
var nanoseconds = durationComponents[1];
var duration = seconds * 1000 + nanoseconds / 1E6;
return () => {
const durationComponents = process.hrtime(start);
const seconds = durationComponents[0];
const nanoseconds = durationComponents[1];
const duration = (seconds * 1000) + (nanoseconds / 1E6);
return duration;

@@ -188,3 +194,3 @@ };

if (this.telegraf) {
var err = new Error('Not supported by Telegraf / InfluxDB');
const err = new Error('Not supported by Telegraf / InfluxDB');
if (callback) {

@@ -200,21 +206,20 @@ return callback(err);

var check = ['_sc', this.prefix + name + this.suffix, status],
metadata = options || {};
const check = ['_sc', this.prefix + name + this.suffix, status], metadata = options || {};
if (metadata.date_happened) {
var timestamp = helpers.formatDate(metadata.date_happened);
const timestamp = helpers.formatDate(metadata.date_happened);
if (timestamp) {
check.push('d:' + timestamp);
check.push(`d:${timestamp}`);
}
}
if (metadata.hostname) {
check.push('h:' + metadata.hostname);
check.push(`h:${metadata.hostname}`);
}
var mergedTags = this.globalTags;
if (tags && typeof(tags) === "object") {
let mergedTags = this.globalTags;
if (tags && typeof(tags) === 'object') {
mergedTags = helpers.overrideTags(mergedTags, tags, this.telegraf);
}
if (mergedTags.length > 0) {
check.push('#' + mergedTags.join(','));
check.push(`#${mergedTags.join(',')}`);
}

@@ -224,11 +229,11 @@

if (metadata.message) {
check.push('m:' + metadata.message);
check.push(`m:${metadata.message}`);
}
// allow for tags to be omitted and callback to be used in its place
if(typeof tags === 'function' && callback === undefined) {
if (typeof tags === 'function' && callback === undefined) {
callback = tags;
}
var message = check.join('|');
const message = check.join('|');
// Service checks are unique in that message has to be the last element in

@@ -257,3 +262,3 @@ // the stat if provided, so we can't append tags like other checks. This

if (this.telegraf) {
var err = new Error('Not supported by Telegraf / InfluxDB');
const err = new Error('Not supported by Telegraf / InfluxDB');
if (callback) {

@@ -270,5 +275,6 @@ return callback(err);

// Convert to strings
var message,
msgTitle = String(title ? title : ''),
msgText = String(text ? text : msgTitle);
let message;
const msgTitle = String(title ? title : '');
let msgText = String(text ? text : msgTitle);
// Escape new lines (unescaping is supported by DataDog)

@@ -278,3 +284,3 @@ msgText = msgText.replace(/\n/g, '\\n');

// start out the message with the event-specific title and text info
message = '_e{' + msgTitle.length + ',' + msgText.length + '}:' + msgTitle + '|' + msgText;
message = `_e{${msgTitle.length},${msgText.length}}:${msgTitle}|${msgText}`;

@@ -284,21 +290,21 @@ // add in the event-specific options

if (options.date_happened) {
var timestamp = helpers.formatDate(options.date_happened);
const timestamp = helpers.formatDate(options.date_happened);
if (timestamp) {
message += '|d:' + timestamp;
message += `|d:${timestamp}`;
}
}
if (options.hostname) {
message += '|h:' + options.hostname;
message += `|h:${options.hostname}`;
}
if (options.aggregation_key) {
message += '|k:' + options.aggregation_key;
message += `|k:${options.aggregation_key}`;
}
if (options.priority) {
message += '|p:' + options.priority;
message += `|p:${options.priority}`;
}
if (options.source_type_name) {
message += '|s:' + options.source_type_name;
message += `|s:${options.source_type_name}`;
}
if (options.alert_type) {
message += '|t:' + options.alert_type;
message += `|t:${options.alert_type}`;
}

@@ -308,3 +314,3 @@ }

// allow for tags to be omitted and callback to be used in its place
if(typeof tags === 'function' && callback === undefined) {
if (typeof tags === 'function' && callback === undefined) {
callback = tags;

@@ -311,0 +317,0 @@ }

{
"name": "hot-shots",
"description": "Node.js client for StatsD, DogStatsD, and Telegraf",
"version": "5.9.2",
"version": "6.0.0",
"author": "Steve Ivy",

@@ -9,4 +9,3 @@ "types": "./types.d.ts",

"Russ Bradberry <rbradberry@gmail.com>",
"Brian Deitte <bdeitte@gmail.com>",
"Mikhail Mazurskiy <mikhail.mazursky@gmail.com>"
"Brian Deitte <bdeitte@gmail.com>"
],

@@ -31,8 +30,8 @@ "keywords": [

"engines": {
"node": ">=0.8.0"
"node": ">=6.0.0"
},
"scripts": {
"coverage": "nyc --reporter=lcov npm test",
"test": "mocha -R spec --timeout 5000 test/index.js",
"lint": "jshint lib/**.js test/**.js",
"coverage": "nyc --reporter=lcov --reporter=text npm test",
"test": "mocha --exit -R spec --timeout 5000 test/*.js",
"lint": "eslint lib/**.js test/**.js",
"pretest": "npm run lint"

@@ -42,4 +41,4 @@ },

"devDependencies": {
"jshint": "2.x",
"mocha": "2.x",
"eslint": "5.9.x",
"mocha": "4.x",
"nyc": "11.x"

@@ -46,0 +45,0 @@ },

@@ -5,12 +5,17 @@ # hot-shots

This project is a fork off of [node-statsd](https://github.com/sivy/node-statsd). This project includes all changes in node-statsd, all open PRs to node-statsd when possible, and some additional goodies (like Telegraf support, child clients, TypeScript types, and more).
This project was originally a fork off of [node-statsd](https://github.com/sivy/node-statsd). This project
includes all changes in the latest node-statsd and many additional changes, including:
* TypeScript types
* Telegraf support
* events
* child clients
* tcp protocol support
* mock mode
* asyncTimer
* much more, including many bug fixes
hot-shots supports Node 6.x and higher.
[![Build Status](https://secure.travis-ci.org/brightcove/hot-shots.png?branch=master)](http://travis-ci.org/brightcove/hot-shots)
## Installation
```
$ npm install hot-shots
```
## Migrating from node-statsd

@@ -137,3 +142,3 @@

client.increment(['these', 'are', 'different', 'stats']);
// Incrementing with tags

@@ -140,0 +145,0 @@ client.increment('my_counter', ['foo', 'bar']);

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