Foundational tracing SDK components for OpenTelemetry JavaScript providing manual instrumentation capabilities
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Samplers control which traces are collected and recorded by making sampling decisions for each span. OpenTelemetry SDK Trace Base provides several built-in sampling strategies including always-on, always-off, ratio-based, and parent-aware samplers.
All samplers implement the base Sampler interface for consistent sampling decisions.
/**
* Interface representing a sampler for controlling trace collection
*/
interface Sampler {
/**
* Checks whether span needs to be created and tracked
* @param context - Parent Context which may contain a span
* @param traceId - Trace ID of the span to be created
* @param spanName - Name of the span to be created
* @param spanKind - Kind of the span to be created
* @param attributes - Initial set of attributes for the span
* @param links - Collection of links associated with the span
* @returns SamplingResult with decision and optional attributes
*/
shouldSample(
context: Context,
traceId: string,
spanName: string,
spanKind: SpanKind,
attributes: Attributes,
links: Link[]
): SamplingResult;
/**
* Returns the sampler name or short description with configuration
*/
toString(): string;
}
/**
* Sampling result containing decision and additional attributes
*/
interface SamplingResult {
/** Sampling decision determining how the span will be handled */
decision: SamplingDecision;
/** Immutable list of attributes to add to the span */
attributes?: Readonly<Attributes>;
/** TraceState to associate with the span through SpanContext */
traceState?: TraceState;
}
/**
* Sampling decision that determines how a span will be recorded and collected
*/
enum SamplingDecision {
/** Span.isRecording() === false, span will not be recorded */
NOT_RECORD,
/** Span.isRecording() === true, but Sampled flag not set */
RECORD,
/** Span.isRecording() === true AND Sampled flag set */
RECORD_AND_SAMPLED
}Sampler that always samples all traces, useful for development and debugging.
/**
* Sampler that samples all traces
*/
class AlwaysOnSampler implements Sampler {
/**
* Always returns RECORD_AND_SAMPLED decision
*/
shouldSample(
context: Context,
traceId: string,
spanName: string,
spanKind: SpanKind,
attributes: Attributes,
links: Link[]
): SamplingResult;
/**
* Returns "AlwaysOnSampler"
*/
toString(): string;
}Usage Examples:
import { BasicTracerProvider, AlwaysOnSampler } from '@opentelemetry/sdk-trace-base';
// Enable sampling for all traces
const provider = new BasicTracerProvider({
sampler: new AlwaysOnSampler()
});
// Useful for development environments
const devProvider = new BasicTracerProvider({
sampler: new AlwaysOnSampler(),
resource: new Resource({
'service.name': 'dev-service',
'deployment.environment': 'development'
})
});Sampler that never samples traces, useful for disabling tracing or testing scenarios.
/**
* Sampler that samples no traces
*/
class AlwaysOffSampler implements Sampler {
/**
* Always returns NOT_RECORD decision
*/
shouldSample(
context: Context,
traceId: string,
spanName: string,
spanKind: SpanKind,
attributes: Attributes,
links: Link[]
): SamplingResult;
/**
* Returns "AlwaysOffSampler"
*/
toString(): string;
}Usage Examples:
import { BasicTracerProvider, AlwaysOffSampler } from '@opentelemetry/sdk-trace-base';
// Disable all tracing
const provider = new BasicTracerProvider({
sampler: new AlwaysOffSampler()
});
// Conditional sampling based on environment
const sampler = process.env.NODE_ENV === 'test'
? new AlwaysOffSampler()
: new AlwaysOnSampler();
const provider = new BasicTracerProvider({ sampler });Sampler that samples a deterministic fraction of traces based on trace ID, ensuring consistent sampling decisions across services.
/**
* Sampler that samples a deterministic fraction of traces based on trace ID
*/
class TraceIdRatioBasedSampler implements Sampler {
/**
* @param ratio - Sampling ratio between 0.0 and 1.0 (default: 0)
*/
constructor(ratio?: number);
/**
* Makes sampling decision based on trace ID hash
* Same trace ID always produces the same decision
*/
shouldSample(
context: Context,
traceId: string,
spanName: string,
spanKind: SpanKind,
attributes: Attributes,
links: Link[]
): SamplingResult;
/**
* Returns "TraceIdRatioBased{ratio}"
*/
toString(): string;
}Behavior Details:
Usage Examples:
import { BasicTracerProvider, TraceIdRatioBasedSampler } from '@opentelemetry/sdk-trace-base';
// Sample 10% of traces
const provider = new BasicTracerProvider({
sampler: new TraceIdRatioBasedSampler(0.1)
});
// Sample 50% of traces
const provider = new BasicTracerProvider({
sampler: new TraceIdRatioBasedSampler(0.5)
});
// Environment-based sampling rate
const samplingRate = parseFloat(process.env.TRACE_SAMPLING_RATE || '0.1');
const provider = new BasicTracerProvider({
sampler: new TraceIdRatioBasedSampler(samplingRate)
});
// No sampling (equivalent to AlwaysOffSampler)
const noSampleProvider = new BasicTracerProvider({
sampler: new TraceIdRatioBasedSampler(0.0)
});Composite sampler that respects parent span's sampling decision when available, otherwise delegates to a root sampler. This ensures sampling consistency across distributed traces.
/**
* Sampler that respects parent span sampling decisions with fallback samplers
*/
class ParentBasedSampler implements Sampler {
constructor(config: ParentBasedSamplerConfig);
/**
* Makes sampling decision based on parent context or delegates to appropriate sampler
*/
shouldSample(
context: Context,
traceId: string,
spanName: string,
spanKind: SpanKind,
attributes: Attributes,
links: Link[]
): SamplingResult;
/**
* Returns string representation with root sampler info
*/
toString(): string;
}
/**
* Configuration for ParentBasedSampler with different samplers for different scenarios
*/
interface ParentBasedSamplerConfig {
/** Required: Sampler to use when there is no parent span */
root: Sampler;
/** Sampler for remote parent that was sampled (default: AlwaysOnSampler) */
remoteParentSampled?: Sampler;
/** Sampler for remote parent that was not sampled (default: AlwaysOffSampler) */
remoteParentNotSampled?: Sampler;
/** Sampler for local parent that was sampled (default: AlwaysOnSampler) */
localParentSampled?: Sampler;
/** Sampler for local parent that was not sampled (default: AlwaysOffSampler) */
localParentNotSampled?: Sampler;
}Sampling Logic:
Usage Examples:
import {
BasicTracerProvider,
ParentBasedSampler,
TraceIdRatioBasedSampler,
AlwaysOnSampler,
AlwaysOffSampler
} from '@opentelemetry/sdk-trace-base';
// Basic parent-based sampling with ratio-based root
const provider = new BasicTracerProvider({
sampler: new ParentBasedSampler({
root: new TraceIdRatioBasedSampler(0.1) // 10% of new traces
})
});
// Advanced parent-based configuration
const provider = new BasicTracerProvider({
sampler: new ParentBasedSampler({
root: new TraceIdRatioBasedSampler(0.05), // 5% of new traces
remoteParentSampled: new AlwaysOnSampler(), // Always continue sampled remote traces
remoteParentNotSampled: new AlwaysOffSampler(), // Never sample unsampled remote traces
localParentSampled: new AlwaysOnSampler(), // Always continue sampled local traces
localParentNotSampled: new TraceIdRatioBasedSampler(0.01) // 1% chance to sample unsampled local
})
});
// Production-ready configuration
const provider = new BasicTracerProvider({
sampler: new ParentBasedSampler({
root: new TraceIdRatioBasedSampler(0.1), // Sample 10% of root traces
// Use defaults for parent-based decisions (respects parent sampling)
})
});Samplers can be configured through environment variables for runtime control.
Environment Variables:
OTEL_TRACES_SAMPLER - Sampler typeOTEL_TRACES_SAMPLER_ARG - Sampler argument (ratio for ratio-based samplers)Supported Sampler Values:
always_off → AlwaysOffSampleralways_on → AlwaysOnSamplertraceidratio → TraceIdRatioBasedSampler (requires OTEL_TRACES_SAMPLER_ARG)parentbased_always_off → ParentBasedSampler with AlwaysOffSampler rootparentbased_always_on → ParentBasedSampler with AlwaysOnSampler rootparentbased_traceidratio → ParentBasedSampler with TraceIdRatioBasedSampler rootUsage Examples:
# Set environment variables
export OTEL_TRACES_SAMPLER=traceidratio
export OTEL_TRACES_SAMPLER_ARG=0.1
# Or parent-based with ratio
export OTEL_TRACES_SAMPLER=parentbased_traceidratio
export OTEL_TRACES_SAMPLER_ARG=0.05// Configuration will be loaded from environment variables
const provider = new BasicTracerProvider({
// Sampler will be built from OTEL_TRACES_SAMPLER env var
// Other configuration can override env vars
resource: new Resource({
'service.name': 'my-service'
})
});You can implement custom samplers by implementing the Sampler interface.
Usage Examples:
import { Sampler, SamplingResult, SamplingDecision } from '@opentelemetry/sdk-trace-base';
// Custom sampler that samples based on operation name
class OperationBasedSampler implements Sampler {
constructor(private sampledOperations: Set<string>) {}
shouldSample(
context: Context,
traceId: string,
spanName: string,
spanKind: SpanKind,
attributes: Attributes,
links: Link[]
): SamplingResult {
const decision = this.sampledOperations.has(spanName)
? SamplingDecision.RECORD_AND_SAMPLED
: SamplingDecision.NOT_RECORD;
return { decision };
}
toString(): string {
return `OperationBasedSampler{${Array.from(this.sampledOperations).join(',')}}`;
}
}
// Use custom sampler
const provider = new BasicTracerProvider({
sampler: new OperationBasedSampler(new Set([
'user-login',
'payment-process',
'critical-operation'
]))
});Install with Tessl CLI
npx tessl i tessl/npm-opentelemetry--sdk-trace-base