diff --git a/README.md b/README.md index b7823d8..1e8980f 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,10 @@ The check method has the following API: // Gauge: Gauge a stat by a specified amount client.gauge('my_gauge', 123.45); + // Gauge: Gauge a stat by a specified amount, but change it rather than setting it + client.gaugeDelta('my_gauge', -10); + client.gaugeDelta('my_gauge', 4); + // Set: Counts unique occurrences of a stat (alias of unique) client.set('my_unique', 'foobar'); client.unique('my_unique', 'foobarbaz'); diff --git a/lib/statsFunctions.js b/lib/statsFunctions.js index 3735346..9db659f 100644 --- a/lib/statsFunctions.js +++ b/lib/statsFunctions.js @@ -200,6 +200,19 @@ function applyStatsFns (Client) { this.sendAll(stat, value, 'g', sampleRate, tags, callback); }; + /** + * Gauges a stat by a delta + * @param stat {String|Array} The stat(s) to send + * @param value The value to send + * @param sampleRate {Number=} The Number of times to sample (0 to 1). Optional. + * @param tags {Array=} The Array of tags to add to metrics. Optional. + * @param callback {Function=} Callback when message is done being delivered. Optional. + */ + Client.prototype.gaugeDelta = function (stat, value, sampleRate, tags, callback) { + const sign = value >= 0 ? '+' : '-'; + this.sendAll(stat, `${sign}${Math.abs(value)}`, 'g', sampleRate, tags, callback); + }; + /** * Counts unique values by a specified amount * @param stat {String|Array} The stat(s) to send diff --git a/test/statsFunctions.js b/test/statsFunctions.js index 846bb2d..68cb547 100644 --- a/test/statsFunctions.js +++ b/test/statsFunctions.js @@ -16,11 +16,12 @@ describe('#statsFunctions', () => { testTypes().forEach(([description, serverType, clientType, metricsEnd]) => { describe(description, () => { - [{ name: 'timing', unit: 'ms', bytes: 14 }, - { name: 'histogram', unit: 'h', bytes: 12 }, - { name: 'distribution', unit: 'd', bytes: 12 }, - { name: 'gauge', unit: 'g', bytes: 12 }, - { name: 'set', unit: 's', bytes: 12 }, + [{ name: 'timing', unit: 'ms', bytes: 14, sign: '' }, + { name: 'histogram', unit: 'h', bytes: 12, sign: '' }, + { name: 'distribution', unit: 'd', bytes: 12, sign: '' }, + { name: 'gauge', unit: 'g', bytes: 12, sign: '' }, + { name: 'gaugeDelta', unit: 'g', bytes: 12, sign: '+' }, + { name: 'set', unit: 's', bytes: 12, sign: '' }, ].forEach(statFunction => { describe(`#${statFunction.name}`, () => { @@ -30,7 +31,7 @@ describe('#statsFunctions', () => { statsd[statFunction.name]('test', 42); }); server.on('metrics', metrics => { - assert.strictEqual(metrics, `test:42|${statFunction.unit}${metricsEnd}`); + assert.strictEqual(metrics, `test:${statFunction.sign}42|${statFunction.unit}${metricsEnd}`); done(); }); }); @@ -41,7 +42,7 @@ describe('#statsFunctions', () => { statsd[statFunction.name]('test', 42, ['foo', 'bar', 'gtag:gvalue1', 'gtag:gvalue2']); }); server.on('metrics', metrics => { - assert.strictEqual(metrics, `test:42|${statFunction.unit}|#gtag:gvalue1,gtag:gvalue2,foo,bar${metricsEnd}`); + assert.strictEqual(metrics, `test:${statFunction.sign}42|${statFunction.unit}|#gtag:gvalue1,gtag:gvalue2,foo,bar${metricsEnd}`); done(); }); }); @@ -54,7 +55,7 @@ describe('#statsFunctions', () => { statsd[statFunction.name]('test', 42, ['foo', 'bar']); }); server.on('metrics', metrics => { - assert.strictEqual(metrics, `test:42|${statFunction.unit}|#foo,bar${metricsEnd}`); + assert.strictEqual(metrics, `test:${statFunction.sign}42|${statFunction.unit}|#foo,bar${metricsEnd}`); done(); }); }); @@ -71,7 +72,7 @@ describe('#statsFunctions', () => { }); }); server.on('metrics', metrics => { - assert.strictEqual(metrics, `foo.test.bar:42|${statFunction.unit}|@0.5${metricsEnd}`); + assert.strictEqual(metrics, `foo.test.bar:${statFunction.sign}42|${statFunction.unit}|@0.5${metricsEnd}`); assert.strictEqual(called, true); done(); }); @@ -91,7 +92,7 @@ describe('#statsFunctions', () => { }); }); server.on('metrics', metrics => { - assert.strictEqual(metrics, `a:42|${statFunction.unit}\nb:42|${statFunction.unit}\n`); + assert.strictEqual(metrics, `a:${statFunction.sign}42|${statFunction.unit}\nb:${statFunction.sign}42|${statFunction.unit}\n`); done(); }); }); @@ -102,7 +103,7 @@ describe('#statsFunctions', () => { statsd[statFunction.name]('test', 42, { foo: 'bar' }); }); server.on('metrics', metrics => { - assert.strictEqual(metrics, `test:42|${statFunction.unit}|#foo:bar${metricsEnd}`); + assert.strictEqual(metrics, `test:${statFunction.sign}42|${statFunction.unit}|#foo:bar${metricsEnd}`); done(); }); }); @@ -115,7 +116,7 @@ describe('#statsFunctions', () => { statsd[statFunction.name]('test', 42, { foo: 'bar' }); }); server.on('metrics', metrics => { - assert.strictEqual(metrics, `test,foo=bar:42|${statFunction.unit}${metricsEnd}`); + assert.strictEqual(metrics, `test,foo=bar:${statFunction.sign}42|${statFunction.unit}${metricsEnd}`); done(); }); }); @@ -326,4 +327,27 @@ describe('#statsFunctions', () => { }); }); }); + + describe('gaugeDelta', () => { + it('Adds a plus sign when the value is positive', done => { + server = createServer('udp', opts => { + statsd = createHotShotsClient(opts, 'client'); + statsd.gaugeDelta('test', 42); + }); + server.on('metrics', metrics => { + assert.strictEqual(metrics, 'test:+42|g'); + done(); + }); + }); + it('Adds a minus sign when the value is negative', done => { + server = createServer('udp', opts => { + statsd = createHotShotsClient(opts, 'client'); + statsd.gaugeDelta('test', -42); + }); + server.on('metrics', metrics => { + assert.strictEqual(metrics, 'test:-42|g'); + done(); + }); + }); + }); }); diff --git a/types.d.ts b/types.d.ts index 9eddbd8..7fa8013 100644 --- a/types.d.ts +++ b/types.d.ts @@ -127,6 +127,11 @@ declare module "hot-shots" { gauge(stat: string | string[], value: number, callback?: StatsCb): void; gauge(stat: string | string[], value: number, sampleRate?: number, callback?: StatsCb): void; + gaugeDelta(stat: string | string[], value: number, sampleRate?: number, tags?: Tags, callback?: StatsCb): void; + gaugeDelta(stat: string | string[], value: number, tags?: Tags, callback?: StatsCb): void; + gaugeDelta(stat: string | string[], value: number, callback?: StatsCb): void; + gaugeDelta(stat: string | string[], value: number, sampleRate?: number, callback?: StatsCb): void; + set(stat: string | string[], value: number | string, sampleRate?: number, tags?: Tags, callback?: StatsCb): void; set(stat: string | string[], value: number | string, tags?: Tags, callback?: StatsCb): void; set(stat: string | string[], value: number | string, callback?: StatsCb): void;