Skip to content

Commit 5245015

Browse files
authored
✨ Add Sampler API (open-telemetry#48)
* 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
1 parent 82bc82c commit 5245015

File tree

4 files changed

+140
-0
lines changed

4 files changed

+140
-0
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* Copyright 2019, OpenTelemetry Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { Sampler, SpanContext } from '@opentelemetry/types';
18+
19+
/** Sampler that samples a given fraction of traces. */
20+
export class ProbabilitySampler implements Sampler {
21+
readonly description = 'ProbabilitySampler';
22+
23+
constructor(private readonly _probability: number = 1) {}
24+
25+
shouldSample(parentContext?: SpanContext) {
26+
if (this._probability >= 1.0) return true;
27+
else if (this._probability <= 0) return false;
28+
return Math.random() < this._probability;
29+
}
30+
}
31+
32+
export const ALWAYS_SAMPLER = new ProbabilitySampler(1);
33+
export const NEVER_SAMPLER = new ProbabilitySampler(0);
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/**
2+
* Copyright 2019, OpenTelemetry Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import * as assert from 'assert';
18+
import {
19+
ProbabilitySampler,
20+
ALWAYS_SAMPLER,
21+
NEVER_SAMPLER,
22+
} from '../../src/trace/sampler/ProbabilitySampler';
23+
24+
describe('ProbabilitySampler', () => {
25+
it('should return a always sampler for 1', () => {
26+
const sampler = new ProbabilitySampler();
27+
assert.strictEqual(
28+
sampler.shouldSample({
29+
traceId: 'd4cda95b652f4a1592b449d5929fda1b',
30+
spanId: '6e0c63257de34c92',
31+
}),
32+
true
33+
);
34+
});
35+
36+
it('should return a always sampler for >1', () => {
37+
const sampler = new ProbabilitySampler(100);
38+
assert.strictEqual(sampler.shouldSample(), true);
39+
});
40+
41+
it('should return a never sampler for 0', () => {
42+
const sampler = new ProbabilitySampler(0);
43+
assert.strictEqual(sampler.shouldSample(), false);
44+
});
45+
46+
it('should return a never sampler for <0', () => {
47+
const sampler = new ProbabilitySampler(-1);
48+
assert.strictEqual(sampler.shouldSample(), false);
49+
});
50+
51+
it('should sample according to the probability', () => {
52+
Math.random = () => 1 / 10;
53+
const sampler = new ProbabilitySampler(0.2);
54+
assert.strictEqual(sampler.shouldSample(), true);
55+
56+
Math.random = () => 5 / 10;
57+
assert.strictEqual(sampler.shouldSample(), false);
58+
});
59+
60+
it('should return true for ALWAYS_SAMPLER', () => {
61+
assert.strictEqual(ALWAYS_SAMPLER.shouldSample(), true);
62+
});
63+
64+
it('should return false for NEVER_SAMPLER', () => {
65+
assert.strictEqual(NEVER_SAMPLER.shouldSample(), false);
66+
});
67+
});

packages/opentelemetry-types/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export * from './distributed_context/EntryValue';
2020
export * from './resources/Resource';
2121
export * from './trace/attributes';
2222
export * from './trace/link';
23+
export * from './trace/Sampler';
2324
export * from './trace/span';
2425
export * from './trace/span_context';
2526
export * from './trace/span_kind';
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* Copyright 2019, OpenTelemetry Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { SpanContext } from './span_context';
18+
19+
/**
20+
* This interface represent a sampler. Sampling is a mechanism to control the
21+
* noise and overhead introduced by OpenTelemetry by reducing the number of
22+
* samples of traces collected and sent to the backend.
23+
*/
24+
export interface Sampler {
25+
/**
26+
* A string that uniquely describes the sampling behavior of this instance.
27+
*/
28+
readonly description: string;
29+
30+
/**
31+
* Checks whether span needs to be created and tracked.
32+
*
33+
* TODO: Consider to add required arguments https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/sampling-api.md#shouldsample
34+
* @param [parentContext] Parent span context. Typically taken from the wire.
35+
* Can be null.
36+
* @returns whether span should be sampled or not.
37+
*/
38+
shouldSample(parentContext?: SpanContext): boolean;
39+
}

0 commit comments

Comments
 (0)