import { Context, Link, SpanAttributes, SpanKind, trace } from "@opentelemetry/api";
import { Sampler, SamplingDecision, SamplingResult, ParentBasedSampler, TraceIdRatioBasedSampler } from "@opentelemetry/sdk-trace-base";
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
import { SimpleSpanProcessor, ConsoleSpanExporter } from "@opentelemetry/sdk-trace-base";
const USER_ID_TO_DROP_TS = "user_to_skip_tracing_ts";
class UserBasedSamplerTs implements Sampler {
private _rootSampler: Sampler;
constructor(rootSampler?: Sampler) {
// Default to a ParentBased sampler that samples 50% of traces if no root is provided.
this._rootSampler = rootSampler ?? new ParentBasedSampler({ root: new TraceIdRatioBasedSampler(0.5) });
}
shouldSample(
context: Context,
traceId: string,
spanName: string,
spanKind: SpanKind,
attributes: SpanAttributes,
links: Link[]
): SamplingResult {
const userId = attributes["user.id"];
if (userId === USER_ID_TO_DROP_TS) {
return {
decision: SamplingDecision.DROP,
attributes: { ...attributes, "sampler.reason": `Dropping span for user.id=${userId}` }
};
}
return this._rootSampler.shouldSample(context, traceId, spanName, spanKind, attributes, links);
}
toString(): string {
return `UserBasedSamplerTs(rootSampler=${this._rootSampler.toString()})`;
}
}
// Example usage:
// async function runSamplerExample() {
// const customSamplerTs = new UserBasedSamplerTs(
// new ParentBasedSampler({ root: new TraceIdRatioBasedSampler(1.0) }) // Sample all non-dropped
// );
// const provider = new NodeTracerProvider({ sampler: customSamplerTs });
// provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
// provider.register();
// const tracer = trace.getTracer("my-app-sampler-example", "0.1.0");
// tracer.startActiveSpan("op_for_dropped_user_ts", { attributes: { "user.id": USER_ID_TO_DROP_TS } }, (span) => {
// console.log("This span (dropped user) should not appear in console.");
// span.end();
// });
// tracer.startActiveSpan("op_for_sampled_user_ts", { attributes: { "user.id": "another_user_ts" } }, (span) => {
// console.log("This span (sampled user) should appear in console.");
// span.end();
// });
// tracer.startActiveSpan("op_without_user_id_ts", (span) => {
// console.log("This span (no user) should appear in console.");
// span.end();
// });
// }
// runSamplerExample();