Skip to content

Commit

Permalink
Add toString method to Sampler API (#79)
Browse files Browse the repository at this point in the history
* Add toString method to Sampler API

* Add comment

* Fix review comment

* fix review comment

* add cap on _probability value

* Normalize _probability in constructor

* Non-number types check, add more tests

* Make default _probability to 0
  • Loading branch information
mayurkale22 authored Jul 12, 2019
1 parent e0d4c61 commit fbd291b
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,26 @@ import { Sampler, SpanContext } from '@opentelemetry/types';

/** Sampler that samples a given fraction of traces. */
export class ProbabilitySampler implements Sampler {
readonly description = 'ProbabilitySampler';

constructor(private readonly _probability: number = 1) {}
constructor(private readonly _probability: number = 0) {
this._probability = this._normalize(_probability);
}

shouldSample(parentContext?: SpanContext) {
if (this._probability >= 1.0) return true;
else if (this._probability <= 0) return false;
return Math.random() < this._probability;
}

toString(): string {
// TODO: Consider to use `AlwaysSampleSampler` and `NeverSampleSampler`
// based on the specs.
return `ProbabilitySampler{${this._probability}}`;
}

private _normalize(probability: number): number {
if (typeof probability !== 'number' || isNaN(probability)) return 0;
return probability >= 1 ? 1 : probability <= 0 ? 0 : probability;
}
}

export const ALWAYS_SAMPLER = new ProbabilitySampler(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {

describe('ProbabilitySampler', () => {
it('should return a always sampler for 1', () => {
const sampler = new ProbabilitySampler();
const sampler = new ProbabilitySampler(1);
assert.strictEqual(
sampler.shouldSample({
traceId: 'd4cda95b652f4a1592b449d5929fda1b',
Expand All @@ -36,6 +36,7 @@ describe('ProbabilitySampler', () => {
it('should return a always sampler for >1', () => {
const sampler = new ProbabilitySampler(100);
assert.strictEqual(sampler.shouldSample(), true);
assert.strictEqual(sampler.toString(), 'ProbabilitySampler{1}');
});

it('should return a never sampler for 0', () => {
Expand All @@ -52,16 +53,37 @@ describe('ProbabilitySampler', () => {
Math.random = () => 1 / 10;
const sampler = new ProbabilitySampler(0.2);
assert.strictEqual(sampler.shouldSample(), true);
assert.strictEqual(sampler.toString(), 'ProbabilitySampler{0.2}');

Math.random = () => 5 / 10;
assert.strictEqual(sampler.shouldSample(), false);
});

it('should return true for ALWAYS_SAMPLER', () => {
assert.strictEqual(ALWAYS_SAMPLER.shouldSample(), true);
assert.strictEqual(ALWAYS_SAMPLER.toString(), 'ProbabilitySampler{1}');
});

it('should return false for NEVER_SAMPLER', () => {
assert.strictEqual(NEVER_SAMPLER.shouldSample(), false);
assert.strictEqual(NEVER_SAMPLER.toString(), 'ProbabilitySampler{0}');
});

it('should handle NaN', () => {
const sampler = new ProbabilitySampler(NaN);
assert.strictEqual(sampler.shouldSample(), false);
assert.strictEqual(sampler.toString(), 'ProbabilitySampler{0}');
});

it('should handle -NaN', () => {
const sampler = new ProbabilitySampler(-NaN);
assert.strictEqual(sampler.shouldSample(), false);
assert.strictEqual(sampler.toString(), 'ProbabilitySampler{0}');
});

it('should handle undefined', () => {
const sampler = new ProbabilitySampler(undefined);
assert.strictEqual(sampler.shouldSample(), false);
assert.strictEqual(sampler.toString(), 'ProbabilitySampler{0}');
});
});
8 changes: 3 additions & 5 deletions packages/opentelemetry-types/src/trace/Sampler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,6 @@ import { SpanContext } from './span_context';
* samples of traces collected and sent to the backend.
*/
export interface Sampler {
/**
* A string that uniquely describes the sampling behavior of this instance.
*/
readonly description: string;

/**
* Checks whether span needs to be created and tracked.
*
Expand All @@ -36,4 +31,7 @@ export interface Sampler {
* @returns whether span should be sampled or not.
*/
shouldSample(parentContext?: SpanContext): boolean;

/** Returns the sampler name or short description with the configuration. */
toString(): string;
}

0 comments on commit fbd291b

Please sign in to comment.