From d28b45594706cabc0b3f9f2caa75c9e6077b45a2 Mon Sep 17 00:00:00 2001 From: Ryan Ling Date: Fri, 12 Jun 2020 08:55:22 +1000 Subject: [PATCH] fix(Metrics): Avoid `hot-shots` type dependency (#7) This fixes a long-standing issue where TypeScript consumers were forced to install `hot-shots` to fix the following compilation error: ```text ../node_modules/seek-koala/lib/metricsMiddleware/metricsMiddleware.d.ts(1,24): error TS2307: Cannot find module 'hot-shots' or its corresponding type declarations. ``` --- src/metricsMiddleware/metricsMiddleware.test.ts | 6 ++---- src/metricsMiddleware/metricsMiddleware.ts | 10 +++------- src/metricsMiddleware/statsD.test.ts | 13 +++++++++++++ src/metricsMiddleware/statsD.ts | 9 +++++++++ 4 files changed, 27 insertions(+), 11 deletions(-) create mode 100644 src/metricsMiddleware/statsD.test.ts create mode 100644 src/metricsMiddleware/statsD.ts diff --git a/src/metricsMiddleware/metricsMiddleware.test.ts b/src/metricsMiddleware/metricsMiddleware.test.ts index b2498e0..811e81a 100644 --- a/src/metricsMiddleware/metricsMiddleware.test.ts +++ b/src/metricsMiddleware/metricsMiddleware.test.ts @@ -29,10 +29,9 @@ describe('metricsMiddleware', () => { expect(mockTiming).toHaveBeenCalledTimes(1); - const [name, latency, sample, tags] = mockTiming.mock.calls[0] as unknown[]; + const [name, latency, tags] = mockTiming.mock.calls[0] as unknown[]; expect(name).toBe('request'); expect(latency).toBeGreaterThanOrEqual(0); - expect(sample).toBeUndefined(); expect(tags).toEqual({ http_status: '201', http_status_family: '2xx', @@ -61,10 +60,9 @@ describe('metricsMiddleware', () => { expect(mockTiming).toHaveBeenCalledTimes(1); - const [name, latency, sample, tags] = mockTiming.mock.calls[0] as unknown[]; + const [name, latency, tags] = mockTiming.mock.calls[0] as unknown[]; expect(name).toBe('request'); expect(latency).toBeGreaterThanOrEqual(0); - expect(sample).toBeUndefined(); expect(tags).toEqual({ http_status: '500', http_status_family: '5xx', diff --git a/src/metricsMiddleware/metricsMiddleware.ts b/src/metricsMiddleware/metricsMiddleware.ts index 309395b..db50937 100644 --- a/src/metricsMiddleware/metricsMiddleware.ts +++ b/src/metricsMiddleware/metricsMiddleware.ts @@ -1,6 +1,7 @@ -import { StatsD } from 'hot-shots'; import Koa from 'koa'; +import { StatsD } from './statsD'; + /** * Returns metrics tags for the passed Koa context * @@ -53,12 +54,7 @@ export const create = ( const durationNanos = process.hrtime.bigint() - startTime; if (!ctx.state.skipRequestLogging) { - metricsClient.timing( - 'request', - Number(durationNanos) / 1e6, - undefined, - tags, - ); + metricsClient.timing('request', Number(durationNanos) / 1e6, tags); } } }; diff --git a/src/metricsMiddleware/statsD.test.ts b/src/metricsMiddleware/statsD.test.ts new file mode 100644 index 0000000..4bf168a --- /dev/null +++ b/src/metricsMiddleware/statsD.test.ts @@ -0,0 +1,13 @@ +import { StatsD as HotShotsStatsD } from 'hot-shots'; + +import { StatsD as VendoredStatsD } from './statsD'; + +describe('statsD', () => { + it('accepts a hot-shots interface', () => { + const hotShots = (true as unknown) as HotShotsStatsD; + + const vendored: VendoredStatsD = hotShots; + + expect(vendored).toBe(true); + }); +}); diff --git a/src/metricsMiddleware/statsD.ts b/src/metricsMiddleware/statsD.ts new file mode 100644 index 0000000..3ee4cf4 --- /dev/null +++ b/src/metricsMiddleware/statsD.ts @@ -0,0 +1,9 @@ +type Tags = { [key: string]: string } | string[]; + +/** + * Vendored from `hot-shots.StatsD` so that TypeScript consumers are not forced + * to install `hot-shots` when they are not using MetricsMiddleware. + */ +export interface StatsD { + timing(stat: string | string[], value: number, tags?: Tags): void; +}