Yet another client for Etsy's statsd

Downloads in past


2851.7.38 years ago9 years agoMinified + gzip package size for uber-statsd-client in KB


Node.js client for statsd.


var createStatsd = require('uber-statsd-client');

var sdc = createStatsd({
    host: 'statsd.example.com'

var timer = new Date();
sdc.increment('some.counter'); // Increment by one.
sdc.gauge('some.gauge', 10); // Set gauge to 10
sdc.timing('some.timer', timer); // Calculates time diff

sdc.close(); // Optional - stop NOW


Apparently a udp based statsd client does not work with cluster in node0.10 or node0.12. I'd recommend finding a tcp based statsd client or not using cluster.


var createStatsd = require('uber-statsd-client')
var sdc = createStatsd({
    host: 'statsd.example.com',
    port: 8124

Available options:


type: String, default: ""
Prefix all stats written by the client with a particular string
prefix value. This defaults to `""`


type: String, default: ""
The hostname where stats should be send. Defaults to


type: Number, default: 8125
The port where stats should be send. Defaults to 8125


type: Number, default: 1000
The UDP socket will auto-close if it has not been written to
within the socket_timeout period. Defaults to `1000`
If socket_timeout is set to 0 then the UDP socket will never
auto close.


type: Number, default: 100
The UDP socket implementation has an internal highWaterMark.
There is a known issue in node core where it will buffer
packets being written to the UDP socket if it's currently
in the "resolving DNS host" state.
When the highWaterMark is reached all packets are dropped
and ignored.


    block?: Number,
    flush?: Number,
    trailingNewLine?: Boolean

The UDP socket uses an internal packet queue that can be
The semantics of the packet queue is that it will write to
the UDP socket if it has buffered at least `block` amount
of bytes OR it has elapsed at least `flush` amount of
By default the packet queue will join multiple messages with
a new line. It will also append a trailing new line,
however you can opt out of the trailing new line by setting
`trailingNewLine` field to `false`.
The block field defaults to 1440 bytes. The flush field defaults to 1000 milliseconds. The trailingNewLine field defaults to true.


    timeToLive?: Number,
    seedIP?: String,
    backoffSettings?: {
        maxDelay?: Number,
        minDelay?: Number,
        retries?: Number,
        factor?: Number

The UDP socket will optionally use a DNS resolver to resolve
DNS once instead of resolving it for every UDP packet
being written.
It's strongly recommended you use the DNS resolver.
The DNS resolver will resolve its DNS lookup based on the
configured `timeToLive`. i.e. it caches the DNS host for
at least that amount of time.
The DNS resolver takes a seedIP value, this is used when
it cannot resolve DNS due to DNS failures and will fallback
to the static IP you gave it.
The DNS resolver retries DNS lookups on DNS failures based on
the `backoffSettings` you supply.
The timeToLive field defaults to five minutes (in milliseconds) The seedIP field has no default. The backoffSettings.maxDelay field defaults to Infinity The backoffSettings.minDelay field defaults to 500 milliseconds The backoffSettings.retries field defaults to 10 retries The backoffSettings.factor field defaults to 2.


isDisabled is an optional predicate function. You can pass in
a predicate function that allows you to disabled the statsd
client at run time.
When this predicate function returns true the EphemeralSocket
will stop writing to the statsd UDP server.

Counting stuff

Counters are supported, both as raw .counter(metric, delta) and with the shortcuts .increment(metric, [delta=1]) and .decrement(metric, [delta=-1]):
sdc.increment('systemname.subsystem.value'); // Increment by one
	sdc.decrement('systemname.subsystem.value', -10); // Decrement by 10
	sdc.counter('systemname.subsystem.value, 100); // Indrement by 100


Sends an arbitrary number to the back-end:
sdc.gauge('what.you.gauge', 100);


Keep track of how fast (or slow) your stuff is:
var start = new Date();
setTimeout(function () {
		sdc.timing('random.timeout', start);
}, 100 * Math.random());
If it is given a Date, it will calculate the difference, and anything else will be passed straight through.
And don't let the name (or nifty interface) fool you - it can measure any kind of number, where you want to see the distribution (content lengths, list items, query sizes, ...)

Stopping gracefully

By default, the socket is closed if it hasn't been used for a second (see socket_timeout in the init-options), but it can also be force-closed with .close():
var start = new Date();
setTimeout(function () {
	sdc.timing('random.timeout', start); // 2 - implicitly re-creates socket.
	sdc.close(); // 3 - Closes socket after last use.
}, 100 * Math.random());
    sdc.close(); // 1 - Closes socket early.
The call is idempotent, so you can call it "just to be sure". And if you submit new metrics later, the socket will automatically be re-created, and a new timeout-timer started.


The library supports getting "child" clients with extra prefixes, to help with making sane name-spacing in apps:
// Create generic client
var sdc = createSDC({host: 'statsd.example.com', prefix: 'systemname');
	sdc.increment('foo'); // Increments 'systemname.foo'
	... do great stuff ...

// Subsystem A
	var sdcA = sdc.getChildClient('a');
	sdcA.increment('foo'); // Increments 'systemname.a.foo'

// Subsystem B
	var sdcB = sdc.getChildClient('b');
	sdcB.increment('foo'); // Increments 'systemname.b.foo'
Internally, they all use the same socket, so calling .close() on any of them will allow the entire program to stop gracefully.

What's broken

Check the GitHub issues.


ISC - see LICENSE.txt.