Documentation menu

OpenTelemetry traces


title: OpenTelemetry traces description: Collect request traces and connect them to captured errors.

Metrics → Traces shows request timelines, service membership, latency and error spans. Collection is scoped to one application and environment by a secret ingest key. No extra trace permission or module is needed: metrics.read reads traces; metrics.write manages collection and deletion.

Connect a server

Create a secret ingest key for the intended environment under API keys. Configure your existing OpenTelemetry HTTP exporter:

OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://YOUR_SPM_HOST/api/v1/otlp/v1/traces
OTEL_EXPORTER_OTLP_TRACES_PROTOCOL=http/protobuf
OTEL_EXPORTER_OTLP_TRACES_HEADERS=Authorization=Bearer YOUR_SECRET_INGEST_KEY
OTEL_SERVICE_NAME=checkout-api
OTEL_BSP_MAX_EXPORT_BATCH_SIZE=512

http/json is also supported. Optional gzip compression uses OTEL_EXPORTER_OTLP_TRACES_COMPRESSION=gzip where the exporter supports it. Set a stable service.name and service.version. Resource environment labels do not override the key's environment.

For a Node service, load instrumentation before application imports:

import { NodeSDK } from "@opentelemetry/sdk-node";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto";
import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";

const sdk = new NodeSDK({
  traceExporter: new OTLPTraceExporter(),
  instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();
// Await sdk.shutdown() in your service's graceful shutdown handler.

Install those official packages and configure the environment above. Instrumentation and W3C context propagation remain under your OpenTelemetry SDK's control. SaaS Pro does not create an unrelated trace or rewrite outgoing request headers.

Connect an OpenTelemetry Collector

A Collector can accept gRPC, browser or other upstream traffic and forward HTTP Protobuf to this endpoint. Keep authentication, CORS, filtering and tenant separation on the Collector. Never put the secret ingest key in browser or mobile code.

exporters:
  otlphttp/saaspro:
    traces_endpoint: https://YOUR_SPM_HOST/api/v1/otlp/v1/traces
    headers:
      Authorization: "Bearer ${env:SPM_INGEST_KEY}"
    compression: gzip
processors:
  batch/saaspro:
    send_batch_size: 128
    send_batch_max_size: 512
service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch/saaspro]
      exporters: [otlphttp/saaspro]

Add this to your existing Collector receiver configuration. Use a separate authenticated pipeline/exporter for each application/environment. OTLP gRPC, metrics and logs are not accepted by this trace endpoint.

The Node, browser and React Native SDKs accept traceContext. Return the active OpenTelemetry span context at capture time:

import { trace } from "@opentelemetry/api";
import { SaaSProMax } from "@saaspro/node";

const spm = new SaaSProMax({
  secretKey: process.env.SPM_INGEST_KEY!,
  host: "https://YOUR_SPM_HOST",
  traceContext: () => trace.getActiveSpan()?.spanContext(),
});

try {
  await performOperation();
} catch (error) {
  spm.captureException(error);
}

Run the operation inside the active span context. An explicit captureException(error, { trace: span.spanContext() }) overrides the callback and works when capturing after the span has ended. Pass { trace: null } to suppress correlation for one error. The context is { traceId, spanId, traceFlags? }: nonzero 32/16-character hexadecimal IDs and optional 0–255 flags. Invalid contexts or throwing callbacks are ignored so they cannot hide the error. Other events can carry context.trace; SDK callbacks also attach it to regular events.

Browser and React Native configuration uses a public key as usual. This only attaches IDs; export spans through an appropriately secured Collector. No OpenTelemetry dependency is added to the default browser bundle.

Open an error's View request trace link, or a trace's Related errors. Cross-links only appear with both module permissions. Correlation requires the same trace ID, application and environment. A missing or expired trace explains its state instead of inventing a timeline.

Collection controls

Settings are per environment, audited and protected against concurrent edits. Console saves require a passkey verified within 10 minutes; shortening retention also requires a reason.

Control Default / limit
Collection Enabled; can be paused
Sample 100%; deterministic by application, environment and trace ID
Daily budget 100,000 new spans; configurable 100–1,000,000; midnight UTC reset
Retention 7 days; configurable 1–30, capped by application retention
Retained storage 200,000 spans and 256 MiB normalized payload per environment; database/index overhead is additional
Per trace 2,000 spans
Per export 512 spans, 2 MiB uncompressed or 1 MiB gzip; 5-second body read limit
Per normalized span 16 KiB; at most 64 accepted attributes, 32 events, 16 links
Request rate Per-key, per-instance token bucket: burst 20 exports, refilling 2 exports/second

Sampling applies consistently to spans sharing a trace ID under the current policy. Changing sampling mid-request or using upstream sampling may leave partial traces. Counts and p95 are calculated from retained traces without extrapolation; duration is first span start to last span end. Service summaries describe traces containing the service. A span with unset status is not proof of success. Explicitly missing parents, cycles and collector truncation are labeled; completeness cannot be guaranteed.

Duplicate (trace ID, span ID) exports with the same normalized content are acknowledged without charging storage again. Conflicting content is discarded; a completed span is immutable. Normalization-policy changes may make a repeated old span conflict. Late parents update the request summary. Spans must start within effective retention, end no more than 60 seconds in the future and last at most 24 hours.

Retention hides old traces immediately and the recurring worker deletes their payloads. A trace expires according to its earliest collected span. Run the worker for physical cleanup; collection stops at the retained cap until space is available. Explicit deletion requires a reason, removes the trace and blocks re-ingestion for 30 days. Related error records have their own retention. Daily collection counters are kept for 90 days.

An optional HTTPS external-viewer URL can contain one {traceId} placeholder. It creates a link to an existing backend; credentials and API tokens must not be embedded in it.

Safe attributes

Technical resource attributes include service name/namespace/version, deployment environment, telemetry SDK name/version/language, cloud provider and region. Span/event attributes include HTTP method/status/route, network protocol, database system/operation and restricted technical query summaries, RPC system/service/method, messaging system/operation, and exception/error type. Text is bounded and common credentials, emails, IP addresses, full URLs and query strings are removed.

Request headers, cookies, raw IP attributes, person identifiers, request/response bodies, SQL statements, exception messages/stack traces and AI prompts are discarded. Up to 20 additional attribute keys may be explicitly enabled for numeric/boolean values only. Sensitive key names are refused. Attribute arrays are capped at eight scalar values. Configure instrumentation to use route templates and technical operation names; do not put customer names or arbitrary payloads in them. The collector cannot infer every form of sensitive free text.

See Database performance for slow calls, repeated-query candidates and the db.query.summary contract.

Responses and troubleshooting

  • 200, empty export response: spans accepted or exact duplicates.
  • 200, partial success: accepted spans remain stored; the response reports discarded span counts. Do not retry partial responses.
  • 400/413/415: fix the payload, batch size, encoding or content type.
  • 401/403: check the secret ingest key, environment, enabled Metrics module, origins and collection switch.
  • 429/503: exporter may retry using Retry-After.

Use Collection health to see the latest authenticated export and today's stored, duplicate, sampled, budget and invalid/deleted/conflicting counts. HTTP Protobuf and JSON use the standard OTLP response envelopes. Browser origins do not receive collector CORS permission; use a server-side Collector.

Management API equivalents are under /api/v1/apps/{app}/metrics/traces, /settings and /{traceId}, with ?env=production|staging|development. Use a Management API token for these read/write routes; use a secret ingest key only for exports. See the generated OpenAPI contract for filters, optimistic revisions and deletion.

Protocol references: OTLP specification, JavaScript exporters, W3C trace context.