Skip to content

Commit

Permalink
✨ Add Sampler API (open-telemetry#48)
Browse files Browse the repository at this point in the history
* Add Sampler API

* Keep Optional SpanContext only to make sampling decision

* Add ProbabilitySampler

* Add ProbabilitySampler

* Make probability private and implement probability sampler

* Add test - should sample based on the probability

* Minor fix
  • Loading branch information
mayurkale22 authored Jul 3, 2019
1 parent 82bc82c commit 5245015
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* Copyright 2019, OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

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) {}

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

export const ALWAYS_SAMPLER = new ProbabilitySampler(1);
export const NEVER_SAMPLER = new ProbabilitySampler(0);
67 changes: 67 additions & 0 deletions packages/opentelemetry-core/test/trace/ProbabilitySampler.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**
* Copyright 2019, OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import * as assert from 'assert';
import {
ProbabilitySampler,
ALWAYS_SAMPLER,
NEVER_SAMPLER,
} from '../../src/trace/sampler/ProbabilitySampler';

describe('ProbabilitySampler', () => {
it('should return a always sampler for 1', () => {
const sampler = new ProbabilitySampler();
assert.strictEqual(
sampler.shouldSample({
traceId: 'd4cda95b652f4a1592b449d5929fda1b',
spanId: '6e0c63257de34c92',
}),
true
);
});

it('should return a always sampler for >1', () => {
const sampler = new ProbabilitySampler(100);
assert.strictEqual(sampler.shouldSample(), true);
});

it('should return a never sampler for 0', () => {
const sampler = new ProbabilitySampler(0);
assert.strictEqual(sampler.shouldSample(), false);
});

it('should return a never sampler for <0', () => {
const sampler = new ProbabilitySampler(-1);
assert.strictEqual(sampler.shouldSample(), false);
});

it('should sample according to the probability', () => {
Math.random = () => 1 / 10;
const sampler = new ProbabilitySampler(0.2);
assert.strictEqual(sampler.shouldSample(), true);

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

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

it('should return false for NEVER_SAMPLER', () => {
assert.strictEqual(NEVER_SAMPLER.shouldSample(), false);
});
});
1 change: 1 addition & 0 deletions packages/opentelemetry-types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export * from './distributed_context/EntryValue';
export * from './resources/Resource';
export * from './trace/attributes';
export * from './trace/link';
export * from './trace/Sampler';
export * from './trace/span';
export * from './trace/span_context';
export * from './trace/span_kind';
Expand Down
39 changes: 39 additions & 0 deletions packages/opentelemetry-types/src/trace/Sampler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Copyright 2019, OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { SpanContext } from './span_context';

/**
* This interface represent a sampler. Sampling is a mechanism to control the
* noise and overhead introduced by OpenTelemetry by reducing the number of
* 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.
*
* TODO: Consider to add required arguments https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/sampling-api.md#shouldsample
* @param [parentContext] Parent span context. Typically taken from the wire.
* Can be null.
* @returns whether span should be sampled or not.
*/
shouldSample(parentContext?: SpanContext): boolean;
}

0 comments on commit 5245015

Please sign in to comment.