From 5de607ed540e68579a65cbaf7a14ee476e09549f Mon Sep 17 00:00:00 2001 From: Tomer <42910634+tomer-friedman@users.noreply.github.com> Date: Thu, 7 Dec 2023 10:23:46 -0800 Subject: [PATCH] feat: filter nextjs (#20) --- packages/sample-app/package.json | 1 + packages/sample-app/src/sample_sampler.ts | 30 ++++++++++++++++ .../traceloop-sdk/src/lib/tracing/index.ts | 2 ++ .../traceloop-sdk/src/lib/tracing/sampler.ts | 36 +++++++++++++++++++ 4 files changed, 69 insertions(+) create mode 100644 packages/sample-app/src/sample_sampler.ts create mode 100644 packages/traceloop-sdk/src/lib/tracing/sampler.ts diff --git a/packages/sample-app/package.json b/packages/sample-app/package.json index 60b75819..ef0f0afe 100644 --- a/packages/sample-app/package.json +++ b/packages/sample-app/package.json @@ -8,6 +8,7 @@ "run:with": "npm run build && node dist/src/sample_with.js", "run:prompt_mgmt": "npm run build && node dist/src/sample_prompt_mgmt.js", "run:sample_vision": "npm run build && node dist/src/sample_vision_prompt.js", + "run:sampler": "npm run build && node dist/src/sample_sampler.js", "lint": "eslint . --ext .ts", "lint:fix": "eslint . --ext .ts --fix" }, diff --git a/packages/sample-app/src/sample_sampler.ts b/packages/sample-app/src/sample_sampler.ts new file mode 100644 index 00000000..87348b1d --- /dev/null +++ b/packages/sample-app/src/sample_sampler.ts @@ -0,0 +1,30 @@ +import * as traceloop from "@traceloop/node-server-sdk"; +import { trace, Span, context } from "@opentelemetry/api"; +import { ConsoleSpanExporter } from "@opentelemetry/sdk-trace-base"; + +trace.getTracer("traceloop.tracer"); + +// No spans should be printed to the console when this file runs (it should be filtered out by the sampler) + +const main = async () => { + traceloop.initialize({ + appName: "sample_sampler", + apiKey: process.env.TRACELOOP_API_KEY, + disableBatch: true, + traceloopSyncEnabled: false, + exporter: new ConsoleSpanExporter(), + }); + + trace + .getTracer("traceloop.tracer") + .startActiveSpan( + "test-span", + { attributes: { "next.span_name": "anything" } }, + context.active(), + async (span: Span) => { + span.end(); + }, + ); +}; + +main(); diff --git a/packages/traceloop-sdk/src/lib/tracing/index.ts b/packages/traceloop-sdk/src/lib/tracing/index.ts index d1d04ea8..c88397ab 100644 --- a/packages/traceloop-sdk/src/lib/tracing/index.ts +++ b/packages/traceloop-sdk/src/lib/tracing/index.ts @@ -13,6 +13,7 @@ import { OpenAIInstrumentation } from "@traceloop/instrumentation-openai"; import { SpanAttributes } from "@traceloop/ai-semantic-conventions"; import { ASSOCATION_PROPERTIES_KEY, WORKFLOW_NAME_KEY } from "./tracing"; import { Telemetry } from "../telemetry/telemetry"; +import { TraceloopSampler } from "./sampler"; let _sdk: NodeSDK; let _spanProcessor: SimpleSpanProcessor | BatchSpanProcessor; @@ -90,6 +91,7 @@ export const startTracing = (options: InitializeOptions) => { spanProcessor: _spanProcessor, traceExporter, instrumentations, + sampler: new TraceloopSampler(), }); _sdk.start(); diff --git a/packages/traceloop-sdk/src/lib/tracing/sampler.ts b/packages/traceloop-sdk/src/lib/tracing/sampler.ts new file mode 100644 index 00000000..85aba0b1 --- /dev/null +++ b/packages/traceloop-sdk/src/lib/tracing/sampler.ts @@ -0,0 +1,36 @@ +import { + Sampler, + SamplingResult, + SamplingDecision, +} from "@opentelemetry/sdk-trace-base"; +import { Context, SpanKind, Attributes, Link } from "@opentelemetry/api"; + +const FILTERED_ATTRIBUTE_KEYS = ["next.span_name"]; + +export class TraceloopSampler implements Sampler { + shouldSample( + _context: Context, + _traceId: string, + _spanName: string, + _spanKind: SpanKind, + attributes: Attributes, + _links: Link[], + ): SamplingResult { + let filter = false; + FILTERED_ATTRIBUTE_KEYS.forEach((key) => { + if (attributes?.[key]) { + filter = true; + } + }); + + return { + decision: filter + ? SamplingDecision.NOT_RECORD + : SamplingDecision.RECORD_AND_SAMPLED, + }; + } + + toString(): string { + return "TraceloopSampler"; + } +}