All files / src/types/client StatsDClient.ts

100% Statements 25/25
50% Branches 2/4
100% Functions 8/8
100% Lines 25/25

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 642x 2x 2x   2x       18x   18x               2x 2x       2x 2x       2x       4x 4x 4x       6x 6x 6x       12x 1x     11x       11x   11x 28x 28x       11x      
import { StatsD, Tags } from 'hot-shots';
import { Constants } from '../Constants';
import { MetricClient } from './MetricClient';
 
export class StatsDClient extends MetricClient {
  protected statsDClient: StatsD;
 
  constructor(hostname: string, portNumber: number, isEnabled = true, mock = false) {
    super(isEnabled);
 
    this.statsDClient = new StatsD({
      host: hostname,
      port: portNumber,
      mock: mock,
    });
  }
 
  gaugeImpl(metricName: string, value: number, attributes: Record<string, string>): void {
    const tags: Tags = this.mapAttributesToTags(attributes);
    this.statsDClient.gauge(metricName, value, undefined, tags);
  }
 
  counterImpl(metricName: string, value: number, attributes: Record<string, string>): void {
    const tags: Tags = this.mapAttributesToTags(attributes);
    this.statsDClient.increment(metricName, value, undefined, tags);
  }
 
  timeImpl(metricName: string, value: number, buckets: number[], attributes: Record<string, string>): void {
    this.recordHistogram(metricName, value, buckets, attributes);
  }
 
  histogramImpl(metricName: string, value: number, buckets: number[], attributes: Record<string, string>): void {
    const combinedAttributes = this.appendBucketsAttribute(buckets, attributes);
    const tags: Tags = this.mapAttributesToTags(combinedAttributes);
    this.statsDClient.timing(metricName, value, undefined, tags);
  }
 
  protected appendBucketsAttribute(buckets: number[], attributes: Record<string, string>): Record<string, string> {
    const clonedAttributes = { ...attributes };
    clonedAttributes[Constants.HistogramBucketAttributeName] = buckets.join(';');
    return clonedAttributes;
  }
 
  protected mapAttributesToTags(attributes: Record<string, string> | undefined): Tags {
    if (attributes === undefined) {
      return {};
    }
 
    return this.sanitizeAttributes(attributes);
  }
 
  private sanitizeAttributes(attributes: Record<string, string>): Record<string, string> {
    const sanitizedAttributes: Record<string, string> = {};
 
    for (const attributeName in attributes) {
      if (attributes[attributeName]) {
        sanitizedAttributes[attributeName] = attributes[attributeName].replace(/[#,:]/g, '_');
      }
    }
 
    return sanitizedAttributes;
  }
}