From 20afb0ee047bc81c5d16adda6cbd3efb935272ea Mon Sep 17 00:00:00 2001 From: Chris Moultrie Date: Thu, 25 Jun 2020 16:51:03 -0400 Subject: [PATCH] Support emitting distribution metrics alongside or instead of histograms --- README.md | 2 +- lib/index.js | 11 +++++++++-- lib/index.test.js | 23 ++++++++++++++++++++--- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index dfb6486..db61efc 100644 --- a/README.md +++ b/README.md @@ -23,8 +23,8 @@ All options are optional. * `protocol` *boolean* include protocol tag. `default = false` * `response_code` *boolean* include http response codes. `default = false` * `delim` *string* char to replace pipe char with in the route `default = '-'` +* `timing_type` *string* the type of metric to emit `histogram`, `distribution`, or `both`. `default = 'histogram'` ## License View the [LICENSE](https://github.com/AppPress/node-connect-datadog/blob/master/LICENSE) file. - diff --git a/lib/index.js b/lib/index.js index e5b2699..ea58d38 100644 --- a/lib/index.js +++ b/lib/index.js @@ -10,6 +10,7 @@ module.exports = function (options) { let protocol = options.protocol || false; let response_code = options.response_code || false; let DELIM = options.delim || '-'; + let timing_type = options.timing_type || 'histogram'; let REGEX_PIPE = /\|/g; /** @@ -44,7 +45,7 @@ module.exports = function (options) { res.end(chunk, encoding); let statTags = [...tags]; - + const route = getRoute(req, base_url); if (route.length > 0) { statTags.push(`route:${route}`); @@ -68,7 +69,13 @@ module.exports = function (options) { datadog.increment(`${stat}.response_code.all`, 1, statTags); } - datadog.histogram(`${stat}.response_time`, new Date() - req._startTime, 1, statTags); + if (['histogram', 'both'].includes(timing_type)) { + datadog.histogram(`${stat}.response_time`, new Date() - req._startTime, 1, statTags); + } + + if (['distribution', 'both'].includes(timing_type)) { + datadog.distribution(`${stat}.dist.response_time`, new Date() - req._startTime, 1, statTags); + } }; next(); diff --git a/lib/index.test.js b/lib/index.test.js index 11cbb9e..f9cf51d 100644 --- a/lib/index.test.js +++ b/lib/index.test.js @@ -2,6 +2,7 @@ const connectDatadog = require("./index"); const mockStatsDImplementation = { histogram: jest.fn(), + distribution: jest.fn(), increment: jest.fn(), } @@ -35,6 +36,7 @@ describe('connectDatadog', () => { afterEach(() => { mockStatsDImplementation.histogram.mockReset() + mockStatsDImplementation.distribution.mockReset() mockStatsDImplementation.increment.mockReset() }) @@ -101,7 +103,10 @@ describe('connectDatadog', () => { let dogstatsd beforeEach(() => { - dogstatsd = { histogram: jest.fn() } + dogstatsd = { + histogram: jest.fn(), + distribution: jest.fn(), + } }) it('gets a value for the dogstatsd option', async () => { @@ -109,6 +114,18 @@ describe('connectDatadog', () => { expect(dogstatsd.histogram).toHaveBeenCalled() }) + it('uses distribution when specified', async () => { + await asyncConnectDatadogAndCallMiddleware({ dogstatsd, timing_type: 'distribution' }); + expect(dogstatsd.histogram).not.toHaveBeenCalled(); + expect(dogstatsd.distribution).toHaveBeenCalled(); + }) + + it('uses both timing types when specified', async () => { + await asyncConnectDatadogAndCallMiddleware({ dogstatsd, timing_type: 'both' }); + expect(dogstatsd.histogram).toHaveBeenCalled(); + expect(dogstatsd.distribution).toHaveBeenCalled(); + }) + it('uses the default value for the dogstatsd option if not passed', async () => { await asyncConnectDatadogAndCallMiddleware({}) expect(mockStatsDImplementation.histogram).toHaveBeenCalled() @@ -213,7 +230,7 @@ describe('connectDatadog', () => { `route:${req.baseUrl}`, `response_code:${res.statusCode}`, ] - + await asyncConnectDatadogAndCallMiddleware({ base_url: true, response_code: true }) expectConnectedToDatadog(stat, statTags, false) expect(next).toHaveBeenCalled() @@ -227,7 +244,7 @@ describe('connectDatadog', () => { const statTags = [ `response_code:${res.statusCode}`, ] - + await asyncConnectDatadogAndCallMiddleware({ response_code: true }) expectConnectedToDatadog(stat, statTags, false) expect(next).toHaveBeenCalled()