From f4ecd88fb03c49746ea8bcb9f6031704d0dea666 Mon Sep 17 00:00:00 2001 From: Scott Richardson Date: Mon, 24 Nov 2025 12:34:53 -0800 Subject: [PATCH 1/2] [trace explorer] update docs to include trace explorer information --- docs.json | 11 +- infra-analytics/getting-started.mdx | 32 ++++-- infra-analytics/send-traces.mdx | 168 ++++++++++++++++++++++++++++ 3 files changed, 198 insertions(+), 13 deletions(-) create mode 100644 infra-analytics/send-traces.mdx diff --git a/docs.json b/docs.json index 20622f152..c6f977dcc 100644 --- a/docs.json +++ b/docs.json @@ -272,6 +272,12 @@ "pages": [ "infra-analytics/overview", "infra-analytics/getting-started", + { + "group": "Traces Explorer", + "pages": [ + "infra-analytics/send-traces" + ] + }, { "group": "Logs Explorer", "pages": [ @@ -1056,7 +1062,8 @@ { "group": "Open Telemetry", "pages": [ - "/infra-analytics/getting-started" + "/infra-analytics/getting-started", + "/infra-analytics/send-traces" ] }, "server/concepts/cloudflare", @@ -1829,4 +1836,4 @@ "slack": "https://statsig.com/slack" } } -} \ No newline at end of file +} diff --git a/infra-analytics/getting-started.mdx b/infra-analytics/getting-started.mdx index 362bd6ac5..d8cc1add3 100644 --- a/infra-analytics/getting-started.mdx +++ b/infra-analytics/getting-started.mdx @@ -8,7 +8,7 @@ This guide helps you setup and send OpenTelemetry telemetry to Statsig so you ca There are two common paths: - Kubernetes/OpenTelemetry Collector: scrape logs and metrics from your cluster and export to Statsig. See [Open Telemetry Logs and Metrics](/server/concepts/open_telemetry) for a more complete guide. -- Applications: export traces, metrics, and logs directly from your app over OTLP/HTTP to Statsig or to your collector. See the quick starts below. +- Applications: export traces, metrics, and logs to your OpenTelemetry Collector (or traces directly from TypeScript/Node). See the quick starts below. **Endpoint & Auth** @@ -16,6 +16,14 @@ There are two common paths: - Auth header: `statsig-api-key: ` + +Direct trace export to the Statsig OTLP endpoint is only available for TypeScript/Node. For all other languages, send traces to your OpenTelemetry Collector and forward from the Collector to Statsig over OTLP/HTTP. + + + +Need a deeper setup guide? See [Open Telemetry Logs and Metrics](/server/concepts/open_telemetry) for collector installation/config, and the [Traces Explorer quick start](/infra-analytics/send-traces) for language-specific trace examples. + + --- ## Application Telemetry quick starts @@ -64,11 +72,12 @@ const sdk = new NodeSDK({ [ATTR_SERVICE_VERSION]: process.env.VERSION || '1', env: process.env.NODE_ENV || 'development', }), - // Optional: enable traces if you want to try out tracing - // traceExporter: new OTLPTraceExporter({ - // url: 'https://api.statsig.com/otlp/v1/traces', - // headers, - // }), + traceExporter: new OTLPTraceExporter({ + url: 'https://api.statsig.com/otlp/v1/traces', + // or + // url: /v1/metrics + headers, + }), metricReader: new PeriodicExportingMetricReader({ exporter: new OTLPMetricExporter({ url: 'https://api.statsig.com/otlp/v1/metrics', @@ -200,11 +209,12 @@ export async function register() { [ATTR_SERVICE_VERSION]: process.env.VERSION || '1', env: process.env.NODE_ENV || 'development', }), - // Optional: enable traces if you want to try out tracing - // traceExporter: new OTLPTraceExporter({ - // url: 'https://api.statsig.com/otlp/v1/traces', - // headers, - // }), + traceExporter: new OTLPTraceExporter({ + url: 'https://api.statsig.com/otlp/v1/traces', + // or + // url: /v1/metrics + headers, + }), metricReader: new PeriodicExportingMetricReader({ exporter: new OTLPMetricExporter({ url: 'https://api.statsig.com/otlp/v1/metrics', diff --git a/infra-analytics/send-traces.mdx b/infra-analytics/send-traces.mdx new file mode 100644 index 000000000..3ce747589 --- /dev/null +++ b/infra-analytics/send-traces.mdx @@ -0,0 +1,168 @@ +--- +title: Traces Explorer Quick Start +sidebarTitle: Quick Start +description: Minimal OTLP/HTTP examples for exporting traces to Statsig's Traces Explorer across popular languages. +--- + + + +Want Logs and Metrics too? See [Getting Started](/infra-analytics/getting-started) for more in-depth OpenTelemetry Collector setup instructions. + + + +Use the OTLP/HTTP traces endpoint to forward spans into Traces Explorer. Authenticate with your Server Secret key in the header: + +- Endpoint: `https://api.statsig.com/otlp/v1/traces` +- Header: `statsig-api-key: ` + + +Note: Direct to API is currently supported for TypeScript/Node only. For all other languages, send traces to your OpenTelemetry Collector and configure it to forward to Statsig over OTLP/HTTP. + +Point non-TypeScript apps to your Collector (for example `http://localhost:4318/v1/traces`) and configure the Collector to forward to Statsig: + +```yaml title="collector.yaml" +receivers: + otlp: + protocols: + http: + +exporters: + otlphttp: + endpoint: https://api.statsig.com/otlp + encoding: json + headers: + statsig-api-key: ${env:STATSIG_SERVER_SDK_SECRET} + +service: + pipelines: + traces: + receivers: [otlp] + exporters: [otlphttp] +``` + + + + +```bash +npm install @opentelemetry/sdk-node @opentelemetry/sdk-trace-node @opentelemetry/sdk-trace-base @opentelemetry/exporter-trace-otlp-http @opentelemetry/resources @opentelemetry/semantic-conventions @opentelemetry/api +``` + +```js +// trace.js +const { NodeSDK } = require('@opentelemetry/sdk-node'); +const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http'); +const { BatchSpanProcessor } = require('@opentelemetry/sdk-trace-base'); +const { Resource } = require('@opentelemetry/resources'); +const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions'); +const { trace } = require('@opentelemetry/api'); + +const sdk = new NodeSDK({ + resource: new Resource({ + [SemanticResourceAttributes.SERVICE_NAME]: 'trace-sample-node', + }), + spanProcessor: new BatchSpanProcessor( + new OTLPTraceExporter({ + url: 'https://api.statsig.com/otlp/v1/traces', + headers: { 'statsig-api-key': process.env.STATSIG_SERVER_SDK_SECRET || '' }, + }), + ), +}); + +sdk.start().then(() => { + const tracer = trace.getTracer('example'); + const span = tracer.startSpan('do-work'); + span.setAttribute('example', true); + span.end(); + + setTimeout(() => sdk.shutdown(), 1000); +}); +``` + + + +```bash +pip install opentelemetry-sdk opentelemetry-exporter-otlp-proto-http +``` + +```python +# trace.py +from opentelemetry import trace +from opentelemetry.sdk.resources import Resource +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.sdk.trace.export import BatchSpanProcessor +from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter + +trace.set_tracer_provider( + TracerProvider(resource=Resource.create({"service.name": "trace-sample-python"})) +) + +exporter = OTLPSpanExporter( + endpoint="http://localhost:4318/v1/traces", # your Collector +) +trace.get_tracer_provider().add_span_processor(BatchSpanProcessor(exporter)) + +tracer = trace.get_tracer(__name__) +with tracer.start_as_current_span("do-work") as span: + span.set_attribute("example", True) + +trace.get_tracer_provider().shutdown() +``` + + + +```bash +go get go.opentelemetry.io/otel/sdk go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp go.opentelemetry.io/otel/semconv/v1.26.0 +``` + +```go +// main.go +package main + +import ( + "context" + "log" + + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp" + "go.opentelemetry.io/otel/sdk/resource" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + semconv "go.opentelemetry.io/otel/semconv/v1.26.0" +) + +func main() { + ctx := context.Background() + + exporter, err := otlptracehttp.New(ctx, + otlptracehttp.WithEndpointURL("http://localhost:4318/v1/traces"), // your Collector + ) + if err != nil { + log.Fatal(err) + } + + tp := sdktrace.NewTracerProvider( + sdktrace.WithBatcher(exporter), + sdktrace.WithResource(resource.NewWithAttributes( + semconv.SchemaURL, + semconv.ServiceNameKey.String("trace-sample-go"), + )), + ) + otel.SetTracerProvider(tp) + + tracer := otel.Tracer("example") + ctx, span := tracer.Start(ctx, "do-work") + span.SetAttributes(attribute.Bool("example", true)) + span.End() + + _ = tp.Shutdown(ctx) +} +``` + + + + + + Need a deeper setup guide? See [Open Telemetry Logs and Metrics](/server/concepts/open_telemetry) for collector installation/config, + and if you want Logs and Metrics too? See [Getting Started](/infra-analytics/getting-started) for + more in-depth OpenTelemetry Collector setup instructions. + From ce00cf52413707d413fdf2d67804f9e2a425b87e Mon Sep 17 00:00:00 2001 From: Scott Richardson Date: Wed, 10 Dec 2025 15:40:55 -0800 Subject: [PATCH 2/2] Fix comments for trace exporter URL in documentation --- infra-analytics/getting-started.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/infra-analytics/getting-started.mdx b/infra-analytics/getting-started.mdx index d8cc1add3..7d57e0669 100644 --- a/infra-analytics/getting-started.mdx +++ b/infra-analytics/getting-started.mdx @@ -75,7 +75,7 @@ const sdk = new NodeSDK({ traceExporter: new OTLPTraceExporter({ url: 'https://api.statsig.com/otlp/v1/traces', // or - // url: /v1/metrics + // url: /v1/traces headers, }), metricReader: new PeriodicExportingMetricReader({ @@ -212,7 +212,7 @@ export async function register() { traceExporter: new OTLPTraceExporter({ url: 'https://api.statsig.com/otlp/v1/traces', // or - // url: /v1/metrics + // url: /v1/traces headers, }), metricReader: new PeriodicExportingMetricReader({