From b287bd66334815f085bb8dc6bba066751fde9400 Mon Sep 17 00:00:00 2001 From: legendecas Date: Tue, 12 Jul 2022 10:54:04 +0800 Subject: [PATCH] feat(sdk-trace-base): move Sampler declaration into sdk-trace-base --- .../opentelemetry-sdk-trace-base/package.json | 1 + .../src/Sampler.ts | 73 +++++++++++++++++++ .../src/config.ts | 3 +- .../opentelemetry-sdk-trace-base/src/index.ts | 14 ++++ .../test/common/Sampler.test.ts | 54 ++++++++++++++ 5 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 packages/opentelemetry-sdk-trace-base/src/Sampler.ts create mode 100644 packages/opentelemetry-sdk-trace-base/test/common/Sampler.test.ts diff --git a/packages/opentelemetry-sdk-trace-base/package.json b/packages/opentelemetry-sdk-trace-base/package.json index 08b27b6ab7b..5ecbcaa2f4f 100644 --- a/packages/opentelemetry-sdk-trace-base/package.json +++ b/packages/opentelemetry-sdk-trace-base/package.json @@ -84,6 +84,7 @@ "sinon": "12.0.1", "ts-loader": "8.3.0", "ts-mocha": "9.0.2", + "tsd": "0.22.0", "typescript": "4.4.4", "webpack": "4.46.0" }, diff --git a/packages/opentelemetry-sdk-trace-base/src/Sampler.ts b/packages/opentelemetry-sdk-trace-base/src/Sampler.ts new file mode 100644 index 00000000000..b4322482101 --- /dev/null +++ b/packages/opentelemetry-sdk-trace-base/src/Sampler.ts @@ -0,0 +1,73 @@ +import { Context, Link, SpanAttributes, SpanKind } from '@opentelemetry/api'; + +/** + * A sampling decision that determines how a {@link Span} will be recorded + * and collected. + */ + export enum SamplingDecision { + /** + * `Span.isRecording() === false`, span will not be recorded and all events + * and attributes will be dropped. + */ + NOT_RECORD, + /** + * `Span.isRecording() === true`, but `Sampled` flag in {@link TraceFlags} + * MUST NOT be set. + */ + RECORD, + /** + * `Span.isRecording() === true` AND `Sampled` flag in {@link TraceFlags} + * MUST be set. + */ + RECORD_AND_SAMPLED, +} + +/** + * A sampling result contains a decision for a {@link Span} and additional + * attributes the sampler would like to added to the Span. + */ +export interface SamplingResult { + /** + * A sampling decision, refer to {@link SamplingDecision} for details. + */ + decision: SamplingDecision; + /** + * The list of attributes returned by SamplingResult MUST be immutable. + * Caller may call {@link Sampler}.shouldSample any number of times and + * can safely cache the returned value. + */ + attributes?: Readonly; +} + +/** + * 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 { + /** + * Checks whether span needs to be created and tracked. + * + * @param context Parent Context which may contain a span. + * @param traceId of the span to be created. It can be different from the + * traceId in the {@link SpanContext}. Typically in situations when the + * span to be created starts a new trace. + * @param spanName of the span to be created. + * @param spanKind of the span to be created. + * @param attributes Initial set of SpanAttributes for the Span being constructed. + * @param links Collection of links that will be associated with the Span to + * be created. Typically useful for batch operations. + * @returns a {@link SamplingResult}. + */ + shouldSample( + context: Context, + traceId: string, + spanName: string, + spanKind: SpanKind, + attributes: SpanAttributes, + links: Link[] + ): SamplingResult; + + /** Returns the sampler name or short description with the configuration. */ + toString(): string; +} diff --git a/packages/opentelemetry-sdk-trace-base/src/config.ts b/packages/opentelemetry-sdk-trace-base/src/config.ts index 4b364b37186..22d68019020 100644 --- a/packages/opentelemetry-sdk-trace-base/src/config.ts +++ b/packages/opentelemetry-sdk-trace-base/src/config.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { diag, Sampler } from '@opentelemetry/api'; +import { diag } from '@opentelemetry/api'; import { AlwaysOffSampler, AlwaysOnSampler, @@ -24,6 +24,7 @@ import { ENVIRONMENT, TraceIdRatioBasedSampler, } from '@opentelemetry/core'; +import { Sampler } from './Sampler'; const env = getEnv(); const FALLBACK_OTEL_TRACES_SAMPLER = TracesSamplerValues.AlwaysOn; diff --git a/packages/opentelemetry-sdk-trace-base/src/index.ts b/packages/opentelemetry-sdk-trace-base/src/index.ts index 3fb4bc2248a..4f328e290a0 100644 --- a/packages/opentelemetry-sdk-trace-base/src/index.ts +++ b/packages/opentelemetry-sdk-trace-base/src/index.ts @@ -23,7 +23,21 @@ export * from './export/ReadableSpan'; export * from './export/SimpleSpanProcessor'; export * from './export/SpanExporter'; export * from './export/NoopSpanProcessor'; +export * from './Sampler'; export * from './Span'; export * from './SpanProcessor'; export * from './TimedEvent'; export * from './types'; + +/** + * These definition should be moved to @opentelemetry/sdk-trace-base + * in the next major release. + */ +export { + AlwaysOffSampler, + AlwaysOnSampler, + ParentBasedSampler, + TraceIdRatioBasedSampler, + IdGenerator, + RandomIdGenerator, +} from '@opentelemetry/core'; diff --git a/packages/opentelemetry-sdk-trace-base/test/common/Sampler.test.ts b/packages/opentelemetry-sdk-trace-base/test/common/Sampler.test.ts new file mode 100644 index 00000000000..b68479546c9 --- /dev/null +++ b/packages/opentelemetry-sdk-trace-base/test/common/Sampler.test.ts @@ -0,0 +1,54 @@ +/* + * Copyright The 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 { context, SpanKind } from '@opentelemetry/api'; +import { expectAssignable } from 'tsd'; +import { + AlwaysOffSampler, + AlwaysOnSampler, + ParentBasedSampler, + Sampler, + SamplingDecision, + SamplingResult, + TraceIdRatioBasedSampler, +} from '../../src'; + +describe('Sampler', () => { + const samplers = [ + new AlwaysOffSampler(), + new AlwaysOnSampler(), + new ParentBasedSampler({ root: new AlwaysOffSampler() }), + new TraceIdRatioBasedSampler(), + ] as const; + + it('Samplers defined in @opentelemetry/core should fit the interface', () => { + for (const sampler of samplers) { + expectAssignable(sampler); + } + }); + + it('Sampler return values should fit SamplerResult', () => { + function expectResult(sampler: T) { + const result = sampler.shouldSample(context.active(), 'trace-id', 'span-name', SpanKind.INTERNAL, {}, []); + expectAssignable(result); + expectAssignable(result.decision); + } + + for (const sampler of samplers) { + expectResult(sampler); + } + }); +});