Skip to content

Commit

Permalink
fix(createStatsDClient): Return full StatsD type (#51)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: the `StatsD` class must be passed as the first argument
of the factory function. The return type will reflect the input type, so
you don't need to perform a type assertion `as StatsD` anymore.

```diff
import { StatsD } from 'hot-shots';
import { createStatsDClient } from 'seek-datadog-custom-metrics';

- export const metricsClient = createStatsDClient(config, errHandler) as StatsD;
+ export const metricsClient = createStatsDClient(StatsD, config, errHandler);
```
  • Loading branch information
72636c authored Nov 17, 2020
1 parent 6b606a2 commit d5558b0
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 14 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ These tags are consistent with tags sent by [Gantry](https://github.com/SEEK-Job
This is intended for containerized services, particularly those deployed with [Gantry](https://github.com/SEEK-Jobs/gantry).

```typescript
import { StatsD } from 'hot-shots';
import { createStatsDClient } from 'seek-datadog-custom-metrics';

// Expects `name`, `version`, `environment` and `metricsServer` properties
Expand All @@ -55,7 +56,7 @@ const errorHandler = (err: Error) => {
};

// Returns a standard hot-shots StatsD instance
const metricsClient = createStatsDClient(config, errorHandler);
const metricsClient = createStatsDClient(StatsD, config, errorHandler);
```

### `createCloudWatchClient`
Expand Down
8 changes: 7 additions & 1 deletion src/createStatsDClient.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { StatsD } from 'hot-shots';

import createStatsDClient from './createStatsDClient';

describe('createStatsDClient', () => {
it('should create a new mock client', () => {
expect(
createStatsDClient({ name: 'test', environment: 'jest', version: '0' }),
createStatsDClient(StatsD, {
name: 'test',
environment: 'jest',
version: '0',
}),
).toBeInstanceOf(Object);
});
});
32 changes: 21 additions & 11 deletions src/createStatsDClient.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
import type { StatsD } from 'hot-shots';

import AppConfig from './AppConfig';
import MetricsClient from './MetricsClient';
import globalTags from './globalTags';

interface InternalStatsD extends MetricsClient {
socket?: {
close(callback?: () => void): void;
};
}

interface StatsD<T extends InternalStatsD> {
new (options?: {
mock?: boolean;
host?: string;
errorHandler?: (err: Error) => void;
prefix?: string;
globalTags?: Record<string, string> | string[];
}): T;
}

/**
* Configuration for building a StatsD client
*/
Expand All @@ -23,20 +37,16 @@ export interface StatsDConfig extends AppConfig {
* The returned client is configured to use a common tagging convention based
* on the application's name, environment and version.
*
* @param StatsD - StatsD class from `hot-shots`
* @param config - Application configuration
* @param errorHandler - Optional error handler function
*/
export default (
export default <T extends InternalStatsD>(
StatsD: StatsD<T>,
config: StatsDConfig,
errorHandler?: (err: Error) => void,
): MetricsClient => {
// Avoid a hard dependency on `hot-shots` for e.g. Lambda CloudWatch users
// This severely angers TypeScript in multiple ways.

// eslint-disable-next-line
const StatsDClass = require('hot-shots').StatsD as typeof StatsD;

const client = new StatsDClass({
): T => {
const client = new StatsD({
// Disable ourselves if there's no configured metrics server
mock: !config.metricsServer,
host: config.metricsServer,
Expand Down
4 changes: 3 additions & 1 deletion src/createTimedSpan.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { StatsD } from 'hot-shots';

import createStatsDClient from './createStatsDClient';
import createTimedSpan from './createTimedSpan';

const metricsClient = createStatsDClient({
const metricsClient = createStatsDClient(StatsD, {
name: 'jest',
version: '0.0.1',
environment: 'dev',
Expand Down

0 comments on commit d5558b0

Please sign in to comment.