diff --git a/src/deterministic-sampler.ts b/src/deterministic-sampler.ts index 41ae08d7..8590c5d5 100644 --- a/src/deterministic-sampler.ts +++ b/src/deterministic-sampler.ts @@ -1,5 +1,6 @@ import { Attributes, Context, Link, SpanKind } from '@opentelemetry/api'; import { + AlwaysOffSampler, AlwaysOnSampler, Sampler, SamplingResult, @@ -29,6 +30,10 @@ export class DeterministicSampler implements Sampler { constructor(sampleRate: number) { this._sampleRate = sampleRate; switch (sampleRate) { + // sample rate of 0 means send nothing + case 0: + this._sampler = new AlwaysOffSampler(); + break; // sample rate of 1 is default, send everything case 1: this._sampler = new AlwaysOnSampler(); diff --git a/src/types.ts b/src/types.ts index f8fcbadb..c122bd30 100644 --- a/src/types.ts +++ b/src/types.ts @@ -72,7 +72,8 @@ export interface HoneycombOptions extends Partial { serviceName?: string; /** The sample rate used to determine whether a trace is exported. - * This must be a whole number greater than 1. Only 1 out of every `sampleRate` traces will be randomly selected to be sent. + * This must be a whole positive number. Only 1 out of every `sampleRate` traces will be randomly selected to be sent. + * Set to 0 to drop everything. * Defaults to 1 (send everything). */ sampleRate?: number; diff --git a/src/util.ts b/src/util.ts index b3db5072..15635b7f 100644 --- a/src/util.ts +++ b/src/util.ts @@ -71,10 +71,10 @@ export const getTracesApiKey = (options?: HoneycombOptions) => { export const getSampleRate = (options?: HoneycombOptions) => { if ( - // sample rate must be a whole integer greater than 0 - options?.sampleRate && - options?.sampleRate > 0 && - Number.isSafeInteger(options?.sampleRate) + // must be a whole positive integer + typeof options?.sampleRate === 'number' && + Number.isSafeInteger(options?.sampleRate) && + options?.sampleRate >= 0 ) { return options?.sampleRate; } diff --git a/test/deterministic-sampler.test.ts b/test/deterministic-sampler.test.ts index b3f4cb7c..cc0744aa 100644 --- a/test/deterministic-sampler.test.ts +++ b/test/deterministic-sampler.test.ts @@ -65,22 +65,22 @@ describe('configureDeterministicSampler', () => { expect(result.attributes).toEqual({ SampleRate: 1 }); }); - test('sample rate of 0 configures inner AlwaysOnSampler', () => { + test('sample rate of 0 configures inner AlwaysOffSampler', () => { const options = { sampleRate: 0, }; const sampler = configureDeterministicSampler(options); expect(sampler).toBeInstanceOf(DeterministicSampler); - expect(sampler.toString()).toBe('DeterministicSampler(AlwaysOnSampler)'); + expect(sampler.toString()).toBe('DeterministicSampler(AlwaysOffSampler)'); const result = getSamplingResult(sampler); - expect(result.decision).toBe(SamplingDecision.RECORD_AND_SAMPLED); - expect(result.attributes).toEqual({ SampleRate: 1 }); + expect(result.decision).toBe(SamplingDecision.NOT_RECORD); + expect(result.attributes).toEqual({ SampleRate: 0 }); }); test('sample rate of -42 configures inner AlwaysOn Sampler', () => { const options = { - sampleRate: 0, + sampleRate: -42, }; const sampler = configureDeterministicSampler(options); expect(sampler).toBeInstanceOf(DeterministicSampler); diff --git a/test/util.test.ts b/test/util.test.ts index 55bd578b..cbead890 100644 --- a/test/util.test.ts +++ b/test/util.test.ts @@ -115,11 +115,11 @@ describe('sample rate', () => { expect(getSampleRate(options)).toBe(2); }); - it('should use default sample rate if provided with 0', () => { + it('should use 0 sample rate if provided with 0', () => { const options = { sampleRate: 0, }; - expect(getSampleRate(options)).toBe(1); + expect(getSampleRate(options)).toBe(0); }); it('should use default sample rate if provided with negative', () => {