From e6deac1ae46a35a9f1c57de0e023ace7900473e1 Mon Sep 17 00:00:00 2001 From: Michael Hoffmann Date: Wed, 3 Jun 2026 16:10:34 +0200 Subject: [PATCH] docs(develop): Add span specification for span-first tracing model Co-Authored-By: Claude Opus 4.6 --- develop-docs/sdk/telemetry/spans/index.mdx | 807 ++++++++++++++++++++- 1 file changed, 805 insertions(+), 2 deletions(-) diff --git a/develop-docs/sdk/telemetry/spans/index.mdx b/develop-docs/sdk/telemetry/spans/index.mdx index aa6ee4c9d5750..907f56283b158 100644 --- a/develop-docs/sdk/telemetry/spans/index.mdx +++ b/develop-docs/sdk/telemetry/spans/index.mdx @@ -1,7 +1,810 @@ --- title: Spans -description: Span creation, sampling, filtering, and data scrubbing within traces. +description: Span creation, sampling, filtering, buffering, and wire format for the span-first tracing model. +spec_id: sdk/telemetry/spans +spec_version: 2.13.0 +spec_status: candidate +spec_depends_on: + - id: sdk/foundations/transport/envelopes + version: ">=1.0.0" + - id: sdk/foundations/trace-propagation + version: ">=1.0.0" +spec_changelog: + - version: 2.13.0 + date: 2026-05-22 + summary: Added span attribute convention guidelines, fixed ignoreSpans examples + - version: 2.12.1 + date: 2026-04-22 + summary: Renamed useragent to user_agent in ingest_settings + - version: 2.12.0 + date: 2026-04-13 + summary: Clarified non-common attributes must only be set on the span they belong to + - version: 2.11.0 + date: 2026-04-09 + summary: Added version and ingest_settings to span envelope item container + - version: 2.10.0 + date: 2026-04-01 + summary: Clarified ignoreSpans child reparenting and beforeSendSpan restrictions + - version: 2.9.0 + date: 2026-03-09 + summary: Added span-on-scope behavior and Noop span trace header propagation + - version: 2.8.0 + date: 2026-02-27 + summary: Added Noop Span specification + - version: 2.7.0 + date: 2026-02-11 + summary: Added span buffer specification + - version: 2.6.0 + date: 2026-01-28 + summary: Required ignoreSpans evaluation before span start, added ignored client report reason + - version: 2.5.0 + date: 2026-01-22 + summary: Added new_trace() API, profiler_id and replay_id common attributes + - version: 2.4.0 + date: 2026-01-19 + summary: Added removeAttribute to Span API + - version: 2.3.0 + date: 2025-12-08 + summary: Added implementation guidelines — traceLifecycle option, captureSpan pipeline, event processor replacement + - version: 2.2.0 + date: 2025-11-25 + summary: Expanded common attribute keys (sentry.op, sentry.span.source, user fields) + - version: 2.1.0 + date: 2025-11-14 + summary: Renamed beforeSendSpans to beforeSendSpan, added span attachments + - version: 2.0.0 + date: 2025-11-04 + summary: "Breaking: Span-first model with span v2 envelope, new Span API, trace propagation" + - version: 1.2.0 + date: 2025-08-13 + summary: Expanded ignoreSpans to support object-based attribute matching + - version: 1.1.0 + date: 2025-02-26 + summary: Added span links specification + - version: 1.0.0 + date: 2024-11-26 + summary: Initial specification — span sampling, filtering, and data scrubbing sidebar_order: 10 --- - + + + + +## Overview + +Spans are the primary telemetry type for Sentry's performance monitoring. A span measures the duration of an operation and carries attributes, links, and status information. This spec covers the span-first ("span streaming") model where spans are sent individually in batched envelopes rather than grouped into transaction events. + +Related specs: +- [Envelopes](/sdk/foundations/transport/envelopes/) — transport format +- [Envelope Items](/sdk/foundations/transport/envelope-items/) — item headers and ingest settings +- [Trace Propagation](/sdk/foundations/trace-propagation/) — `sentry-trace` and `baggage` headers, dynamic sampling context +- [Scopes & Attributes](/sdk/foundations/state-management/scopes/attributes/) — scope-level attribute propagation +- [Span Data Conventions](/sdk/telemetry/traces/span-data-conventions/) — attribute naming conventions +- [Span Operations](/sdk/telemetry/traces/span-operations/) — operation naming conventions +- [Trace Origin](/sdk/telemetry/traces/trace-origin/) — origin naming scheme +- [Span Links](/sdk/telemetry/traces/span-links/) — linking spans across traces + +--- + +## Concepts + +**Span**: A timed operation with a name, attributes, status, and parent relationship. Spans form trees within a trace. + +**Root Span**: The topmost span in a distributed span tree. It has no parent span. Groups its children with a representative name such as `GET /`. + +**Segment Span**: The topmost span within a service boundary. Has a `parent_span_id` pointing to a remote span from the upstream service. A segment span on the originating service is also the root span of the entire tree. + +**Noop Span**: A span implementing the full Span Interface that records no data and has no influence on the trace hierarchy. Returned when a span should not be recorded. + +**Active Span**: A span attached to the current scope. Child spans started while an active span exists become its children. + +**Span-First / Span Streaming**: The `traceLifecycle: 'stream'` mode where spans are captured individually via `captureSpan`, buffered, and sent in batched envelopes — as opposed to the legacy transaction model (`traceLifecycle: 'static'`). + +SDKs **MUST NOT** expose names like "segment span" to users and **SHOULD NOT** expose "root span" if avoidable. + +--- + +## Behavior + + + +### Trace Lifecycle Option + +SDKs **MUST** expose a top-level `traceLifecycle` (or `trace_lifecycle`) init option controlling whether traces are sent as transactions or as spans (v2). + +- Allowed values **MUST** be `'static'` and `'stream'`. +- The SDK **MUST** default to `'static'` (transaction-based). +- Span-first behavior **MUST** only apply when `traceLifecycle` is set to `'stream'`. + + + + + +### Starting Spans + +SDKs **MUST** expose at least one API to start a span. + +- Spans **MUST** be started as active by default. Any span started while the initial span is active **MUST** become a child of the active span. +- If `active: false`, the span **MUST** be started as inactive — spans started while it is running **MUST NOT** become its children. +- If a `Span` is passed via `parentSpan`, it **MUST** take precedence over the currently active span. +- If `null` is passed via `parentSpan`, the new span **MUST** be started as a root/segment span. +- SDKs **MUST NOT** end spans automatically from the default `startSpan` API. SDKs **MAY** provide additional APIs that auto-end spans (e.g. callback-based, context managers). +- `startSpan` **MUST** always return a span instance, even if the trace is negatively sampled. + +SDKs **MUST NOT** expose APIs like `Span::startChild`. The `parentSpan` option serves this purpose. + +#### `parentSpan` Three-State Behavior + +The `parentSpan` parameter has three states: `undefined`, `null`, and a span instance. + +For languages without an `undefined` state, SDKs **SHOULD** model this using platform-appropriate mechanisms: method overloading, a default sentinel value, or enum types. + +If `parentSpan` references a span that has already ended, the SDK **SHOULD** still create the new span as its child. + + + + + +### Setting Spans on Scope + +It **MUST** be possible to attach a span to a scope. In SDKs implementing the three-scope model, the span **SHOULD** be set on the current scope. + +When a span is attached to a scope, a reference to the previous span **MUST** be stored. The previous span **MUST** be re-attached when the currently active span ends. + +If a span is started with `active: true`, it **MUST** be attached to the scope. If `active: false`, it **SHOULD NOT** be attached to the scope. + +If a Noop span would be a segment (no currently active span, or `parentSpan: null`), it **MAY** be set on the scope so children inherit its negative sampling decision. + + + + + +### Noop Span + +A Noop span implements the full [Span Interface](#span-interface) but records no data. + +`startSpan` **MUST** return a Noop span in the following scenarios: +- The span's trace is negatively sampled. +- The span matches an `ignoreSpans` pattern. + +#### Noop Span Behavior + +- All mutating methods (`setAttribute`, `setAttributes`, `removeAttribute`, `setStatus`, `setName`, `addLink`, `addLinks`, `end`) **MUST** be no-ops — they **MUST NOT** record or store data. +- Getter methods (`getName`, `getAttributes`) **SHOULD** return empty/default values. +- A Noop span **MUST NOT** be sent to Sentry. +- If a Noop span is active, its dummy properties **MUST NOT** populate outgoing trace headers. Headers **MUST** be populated from the propagation context instead. Custom APIs like `getTraceparent` and `getBaggage` **MUST** also use the propagation context. (since 2.9.0) + +#### Default Property Values + +For platforms with non-nullable span properties: + +| Property | Default Value | +|----------|---------------| +| `traceId` | `00000000000000000000000000000000` (32 zero hex chars) | +| `spanId` | `0000000000000000` (16 zero hex chars) | +| `name` | Empty string `""` | +| `attributes` | Empty map `{}` | +| `status` | `ok` | + +For nullable platforms, **MUST** return `null` instead. + + + + + +### Sampling + +Sampling **MUST** only apply to root spans. The APIs **MUST** be optimized for trace completeness and conclusive sampling decisions. + +#### `tracesSampleRate` + +The SDK **MUST** default `tracesSampleRate` to `0.0`. When starting a root span, the rate is compared against a random number in `[0.0, 1.0)`. + +#### `tracesSampler` + +If configured, `tracesSampler` **MUST** replace `tracesSampleRate`. The callback **MUST** receive sufficient arguments for users to define custom rules (e.g. span attributes, HTTP headers). The return value **MUST** be a float in `[0.0, 1.0]`. + +If no `tracesSampler` is configured, a propagated sampling decision via the traceparent takes precedence over `tracesSampleRate`. Defining a `tracesSampler` **MAY** disable this behavior. + + + + + +### Filtering + +The SDK **MUST** implement a mechanism for users to filter spans. The result **MUST** be binary. + +#### `ignoreSpans` + +The `ignoreSpans` option **MUST** accept a string, RegExp, or glob pattern matched against the span name. + +Furthermore, `ignoreSpans` **SHOULD** accept objects with patterns matching the span name and/or span attributes. String attribute values **MUST** be matched the same way as span names (contains for strings, match for patterns). Other attribute value types **MUST** strictly equal the provided value. + +#### Implementation Requirements + +1. `ignoreSpans` patterns **MUST** be evaluated **before** the span is started. (since 2.6.0) +2. Patterns **MUST** apply to all spans, including root/segment spans. + - If a pattern matches the root span, the span and all its children **MUST** be ignored. + - If a pattern matches a child span, the child **MUST** be ignored but its children **MUST** be reparented to the ignored span's parent. (since 2.10.0) +3. If a span is ignored, the SDK **MUST** record a client report with the `ignored` discard reason and `span` category. (since 2.6.0) + - For each ignored child span, emit one outcome per span. + - For each ignored segment span, emit one outcome for the segment and one per child span. + + + + + +### Data Scrubbing + +#### `beforeSendSpan` + +The `beforeSendSpan` callback **MUST NOT** allow removal of spans from the span tree. It receives a deep copy of a span. (since 2.1.0) + +Users **MAY** mutate any exposed properties for sanitization. The return value **MUST** be merged with the original span prior to emission. (since 2.10.0) + + + + + +### Trace Propagation + +#### Continue an Incoming Trace + +The SDK **MUST** expose a method to extract traceparent and baggage from incoming headers and apply them to the applicable scope. The method **MUST NOT** create a new segment span on its own. + +The function signature **MAY** require explicitly passing `sentry-trace` and `baggage`, or **MAY** accept a dictionary of headers. + +#### Continue an Outgoing Trace + +The SDK **MUST** expose methods to fetch the required information (traceparent, baggage) for downstream services to continue the trace. + +#### Start a New Trace + +The SDK **MUST** offer a method to clear trace propagation data, allowing spans to be created with a fresh new trace. (since 2.5.0) + + + + + +### Single-Span Processing Pipeline + +SDKs **MUST** implement a `captureSpan` API that takes a single span once it ends, processes it, and enqueues it into the span buffer. This **SHOULD** be a method on the `Client`. + +Processing order: + +1. Accept any span that has ended (has an `end_timestamp`). +2. Obtain current, isolation, and global scopes; merge scope data. +3. Apply [common span attributes](#common-attribute-keys) from client and merged scope data to every span. +4. Apply scope attributes to every span. +5. Apply `contexts` and `request` data from merged scopes to the **segment span only**. +6. Apply span processing hooks (event processor replacements). +7. Apply `beforeSendSpan`. +8. Enqueue the span into the span buffer. + +The `captureSpan` pipeline **MUST NOT**: +- Drop any span +- Buffer spans before enqueuing +- Modify span relationships + + + + + +### Span Buffer + +The span buffer batches spans, constructs envelopes, and forwards them to the transport. + +1. The buffer **MUST** bucket spans by trace ID. When flushing, the buffer **MUST** create distinct envelopes for each trace ID. +2. The buffer **MUST NOT** add more than 1000 spans per envelope. If more than 1000 spans are held for a trace, the buffer **MUST** batch into multiple envelopes. +3. When the buffer drops spans, it **MUST** record a client report with the exact number of spans dropped. +4. The buffer **MAY** ignore priority-based scheduling with other telemetry categories. +5. The buffer **MUST** implement the following flushing behavior: + - Flush on a regular interval, every 5 seconds (SDKs **MAY** adjust based on platform needs). + - Flush a trace bucket when it reaches the 1000 spans limit. + - Flush when a trace bucket reaches 5MB (SDKs **MAY** adjust, but **MUST NOT** exceed 10MB). + - Flush when `SentrySDK.flush()` is called. + - Flush and stop on `SentrySDK.close()`. The buffer **MUST** stop accepting new spans to prevent unbounded memory use. + +#### Buckets per Trace ID + +A recommended design is a map of **trace ID → list of spans**. SDKs **MAY** use other structures (e.g. a fixed ring buffer) as long as the requirements above are met. + +When the span buffer adds a span, it **MUST** add it to the bucket for that span's trace ID. When no bucket exists, it **MUST** create one. After forwarding spans from a bucket, it **MUST** remove all spans and delete the bucket. + +#### Serialization and Dynamic Sampling Context + +SDKs **SHOULD** materialize and freeze the DSC as late as possible: + +- The buffer **SHOULD** enqueue spans but only create the final envelope at **flush time**. +- At flush time, the buffer **SHOULD** materialize and freeze the DSC on the segment span if not already done. + + + + + +### Span Links + +Links connect spans to other spans or traces, enabling cross-trace relationships. + +- Links **MUST** only link to other spans (not errors or other event types). +- SDKs **MUST** expose `addLink` and `addLinks` on the Span interface. +- SDKs **SHOULD** allow specifying `links` in `startSpan` options. +- If the `links` array is empty, it **MAY** be omitted from the envelope. + +#### Link Types + +The `sentry.link.type` attribute on a link defines predefined semantics: + +| `sentry.link.type` | Usage | +|---------------------|-------| +| `previous_trace` | Linking a navigation span to the previous pageload span | +| `next_trace` | Linking a pageload span to the next navigation span | + +#### `previous_trace` Behavior + +On root span start: +- Check if there is a previous span context stored. If yes, add a link with `sentry.link.type: 'previous_trace'`. +- Store the new root span context for the next trace. + +Sampled root spans **SHOULD** still link to a previous negatively sampled root span. SDKs **MUST NOT** skip negatively sampled traces to link to an earlier positively sampled one. + + + + + +### Span Attachments + +To associate an attachment with a span, submit a [trace attachment](/sdk/telemetry/attachments/#trace-attachments) item with an additional `span_id` item header. The attachment **SHOULD** be in the same envelope as the span. + +- `span_id` identifies the owning span. The attachment is dropped with the span if the span is dropped. +- The SDK **MAY** set `span_id` to explicit `null`, meaning "owned by spans" but not by a specific one — the attachment can be dropped if span quota is exceeded, but not with a specific span. + + + + + +### Attribute Conventions + +Attributes outside the [common attribute keys](#common-attribute-keys) list **MUST** only be attached to the span they conceptually belong on, and **MUST NOT** be propagated to children. Attributes mirroring transaction context data **SHOULD** only be set on the segment span. + +All attributes set on a streamed span **MUST** use keys defined in [Sentry Conventions](https://getsentry.github.io/sentry-conventions/) before introduction in an SDK. (since 2.13.0) + +Empty attributes **MUST** be omitted. + + + +--- + +## Wire Format + +### Span v2 Envelope Header + +The envelope header **MUST** contain the same properties as previously with transactions. There are no special requirements beyond those for standard envelopes. + +Unlike transactions, envelope headers for spans **REQUIRE** [Dynamic Sampling Context](/sdk/foundations/trace-propagation/dynamic-sampling-context/). See also [Envelope Headers](/sdk/foundations/transport/envelopes/#headers). + +### Span v2 Envelope Item Header + +| Property | Type | Required | Since | Description | +|----------|------|----------|-------|-------------| +| `type` | string | Yes | 2.0.0 | **MUST** be `"span"` | +| `item_count` | integer | Yes | 2.0.0 | Number of span items in the payload | +| `content_type` | string | Yes | 2.0.0 | **MUST** be `"application/vnd.sentry.items.span.v2+json"` | + +### Span v2 Envelope Item Payload + +The payload is a JSON object that **MUST** include an `items` array of span objects. The payload **MAY** also include top-level `version` and `ingest_settings` fields. (since 2.11.0) + +```json +{ + "version": 2, + "ingest_settings": { + "infer_ip": "auto", + "infer_user_agent": "auto" + }, + "items": [{..span..}, {..span..}] +} +``` + +The `items` array **MUST** contain at least one and at most 1000 span objects. + +See the [Ingest Settings](/sdk/foundations/transport/envelope-items/#ingest-settings) spec for the full `ingest_settings` field reference. (since 2.11.0) + +### Span Properties + +| Property | Type | Required | Since | Description | +|----------|------|----------|-------|-------------| +| `trace_id` | string | Yes | 2.0.0 | 32-character lowercase hexadecimal string | +| `span_id` | string | Yes | 2.0.0 | 16-character lowercase hexadecimal string | +| `parent_span_id` | string | No | 2.0.0 | 16-character lowercase hexadecimal string | +| `name` | string | Yes | 2.0.0 | Low-cardinality description (e.g. `"GET /users"`) | +| `status` | string | Yes | 2.0.0 | Either `"ok"` or `"error"` | +| `is_segment` | boolean | Yes | 2.0.0 | Whether the span is a segment span | +| `start_timestamp` | number | Yes | 2.0.0 | Unix timestamp with fractional microseconds | +| `end_timestamp` | number | Yes | 2.0.0 | Unix timestamp with fractional microseconds | +| `attributes` | object | No | 2.0.0 | Key-value pairs of additional metadata | +| `links` | array | No | 1.1.0 | Array of link objects connecting to other spans | + +### Common Attribute Keys + +All attributes below **MUST** be attached to every span emitted from the SDK, depending on the platform. Empty attributes **MUST** be omitted. + +| Attribute Key | Type | Since | Description | +|---------------|------|-------|-------------| +| `sentry.op` | string | 2.2.0 | The [span op](/sdk/telemetry/traces/span-operations/) | +| `sentry.release` | string | 2.0.0 | Application release version | +| `sentry.environment` | string | 2.0.0 | Environment name | +| `sentry.segment.name` | string | 2.0.0 | Segment name (e.g. `"GET /users"`) | +| `sentry.segment.id` | string | 2.0.0 | Segment span ID | +| `sentry.span.source` | string | 2.2.0 | Source of the span name. **MUST** be set on segment spans, **MAY** be set on child spans. See [Sentry Conventions](https://github.com/getsentry/sentry-conventions/blob/main/model/attributes/sentry/sentry__span__source.json). | +| `sentry.profiler_id` | string | 2.5.0 | ID of the running continuous profiler | +| `sentry.replay_id` | string | 2.5.0 | ID of the running replay | +| `os.name` | string | 2.0.0 | Operating system name | +| `browser.name` | string | 2.0.0 | Browser name | +| `user.id` | string | 2.0.0 | User ID | +| `user.email` | string | 2.0.0 | User email | +| `user.ip_address` | string | 2.0.0 | User IP address | +| `user.name` | string | 2.0.0 | User name | +| `thread.id` | string | 2.0.0 | Thread ID | +| `thread.name` | string | 2.0.0 | Thread name | +| `sentry.sdk.name` | string | 2.0.0 | Sentry SDK name | +| `sentry.sdk.version` | string | 2.0.0 | Sentry SDK version | +| `sentry.origin` | string | 2.0.0 | [Trace origin](/sdk/telemetry/traces/trace-origin/) | +| `sentry.platform` | string | 2.0.0 | Platform identifier | +| `sentry.transaction_info.source` | string | 2.0.0 | Transaction name source | + +### Attribute Value Format + +Each attribute value is an object with `type`, `value`, and optional `unit`: + +```json +{ + "sentry.release": { + "type": "string", + "value": "1.0.0" + }, + "http.response.status_code": { + "type": "integer", + "value": 200 + }, + "session.duration": { + "type": "integer", + "value": 164, + "unit": "second" + } +} +``` + +### Link Object Properties + +| Property | Type | Required | Since | Description | +|----------|------|----------|-------|-------------| +| `span_id` | string | Yes | 1.1.0 | 16-character hexadecimal string | +| `trace_id` | string | Yes | 1.1.0 | 32-character hexadecimal string | +| `sampled` | boolean | No | 1.1.0 | Whether the linked trace was sampled | +| `attributes` | object | No | 1.1.0 | Metadata about the link relationship | + +### Data Types and Formats + +**Timestamps** use Unix time with fractional microseconds: `1742921669.158209` + +**Trace ID**: 32-character (128-bit) lowercase hexadecimal string. + +**Span ID**: 16-character (64-bit) lowercase hexadecimal string. + +--- + +## Public API + +### Span Interface + +SDKs **MUST** implement the following interface at minimum: + +| Method | Parameters | Returns | Since | Description | +|--------|-----------|---------|-------|-------------| +| `end` | `endTimestamp?: SpanTimeInput` | void | 2.0.0 | Ends the span. Records end timestamp. | +| `setAttribute` | `key: string, value: SpanAttributeValue \| undefined` | this | 2.0.0 | Sets a single attribute. | +| `setAttributes` | `attributes: SpanAttributes` | this | 2.0.0 | Sets multiple attributes. | +| `removeAttribute` | `key: string` | this | 2.4.0 | Removes an attribute. | +| `setStatus` | `status: 'ok' \| 'error'` | this | 2.0.0 | Sets the span status. | +| `setName` | `name: string` | this | 2.0.0 | Sets the span name. | +| `addLink` | `link: SpanLink` | this | 1.1.0 | Adds a single link. | +| `addLinks` | `links: SpanLink[]` | this | 1.1.0 | Adds multiple links. | +| `getName` | — | string | 2.0.0 | Returns the span name. | +| `getAttributes` | — | Record | 2.0.0 | Returns all attributes. | + +SDKs **MAY** implement additional methods (e.g. `getStatus()`, `spanContext()`). + +SDK implementers **SHOULD** disallow direct mutation of span properties without setters. SDK implementers **MAY** disallow direct read access. + +### `startSpan` Options + +| Option | Required | Since | Description | +|--------|----------|-------|-------------| +| `name` | Yes | 2.0.0 | Span name. **MUST** be set by users. | +| `attributes` | No | 2.0.0 | Initial attributes. | +| `parentSpan` | No | 2.0.0 | Parent span. See [three-state behavior](#parentspan-three-state-behavior). | +| `active` | No | 2.0.0 | Whether the span should be active (default: `true`). | +| `links` | No | 1.1.0 | Initial span links. | + +### Trace Propagation APIs + +| API | Since | Description | +|-----|-------|-------------| +| `continueTrace` | 2.0.0 | Extracts traceparent and baggage from incoming headers and applies to scope. | +| `getTraceData` / `getTraceparent` + `getBaggage` | 2.0.0 | Returns trace data for outgoing requests. | +| `startNewTrace` / `new_trace` | 2.5.0 | Clears propagation data, starts a fresh trace. | + +### Configuration Options + +| Option | Type | Default | Since | Description | +|--------|------|---------|-------|-------------| +| `traceLifecycle` | `'static' \| 'stream'` | `'static'` | 2.3.0 | Controls transaction vs span-first mode. | +| `tracesSampleRate` | `number` | `0.0` | 1.0.0 | Float in `[0.0, 1.0]`, sampling rate for root spans. | +| `tracesSampler` | `function` | — | 1.0.0 | Callback returning per-trace sample rate. | +| `ignoreSpans` | `array` | — | 1.0.0 | Patterns to filter out spans. | +| `beforeSendSpan` | `function` | — | 1.0.0 | Callback for data scrubbing. | + +### Utility APIs + +SDKs **MAY** expose additional utility APIs: + +- `Scope::getSpan()` — returns the currently active span. +- `Scope::_INTERNAL_getSegmentSpan()` — returns the segment span (**MUST NOT** be documented for users). + +--- + +## Examples + +### SDK API Usage + +```ts {tabTitle:TypeScript} +const checkoutSpan = Sentry.startSpan({ + name: 'on-checkout-click', + attributes: { 'user.id': '123' } +}) + +const validationSpan = Sentry.startSpan({ name: 'validate-shopping-cart' }) +startFormValidation().then((result) => { + validationSpan.setAttribute('valid-form-data', result.success); + validationSpan.end(); +}) + +const processSpan = Sentry.startSpan({ + name: 'process-order', + parentSpan: checkoutSpan +}); +processOrder().then((result) => { + processSpan.setAttribute('order-processed', result.success); + processSpan.end(); +}).catch((error) => { + processSpan.setStatus('error'); + processSpan.end(); +}); + +const unrelatedSpan = Sentry.startSpan({ + name: 'log-order', + parentSpan: null +}); +logOrder() +unrelatedSpan.end(); + +on('checkout-finished', ({ timestamp }) => { + checkoutSpan.end(timestamp); +}) +``` + +```Python {tabTitle:Python} +with sentry_sdk.start_span(name="checkout", attributes={"user.id": "123"}) as checkout_span: + with sentry_sdk.start_span(name="process-order") as process_order_span: + result = process() + process_order_span.set_attribute("order-status", result.message) + + with sentry_sdk.start_span(name="process-payment") as process_payment_span: + try: + result = process_payment() + process_payment_span.set_attribute("order-status", result.message) + except: + process_payment_span.status = "error" + + span = sentry_sdk.start_span(name="log-order", parent_span=None) + log_order() + span.end() +``` + +```Dart {tabTitle:Dart} +final checkoutSpan = Sentry.startSpan( + 'on-checkout-click', + attributes: { + 'user.id': SentryAttribute.string('123'), + }, +); + +final processSpan = Sentry.startSpan( + 'process-order', + parentSpan: checkoutSpan, +); + +processOrder().then((result) { + processSpan.setAttribute('order-processed', SentryAttribute.bool(result.success)); + processSpan.end(); +}).catchError((error) { + processSpan.status = SpanV2Status.error; + processSpan.end(); +}); + +final unrelatedSpan = Sentry.startSpan( + 'log-order', + parentSpan: null, +); +logOrder(); +unrelatedSpan.end(); + +on('checkout-finished', (timestamp) { + checkoutSpan.end(endTimestamp: timestamp); +}); +``` + +### Trace Propagation Usage + +```js {tabTitle:TypeScript} +// Continue an incoming trace +Sentry.continueTrace({ + sentryTrace: request.headers['sentry-trace'], + baggage: request.headers['baggage'], +}, () => { + Sentry.startSpan({ name: 'handle-request' }, () => { + // ... + }); +}) + +// Propagate to downstream services +const traceData = Sentry.getTraceData() + +// Start a fresh trace +Sentry.startNewTrace(() => { + Sentry.startSpan({ name: 'new-operation' }, () => {}); +}) +``` + +```python {tabTitle:Python} +# Continue an incoming trace +sentry_sdk.continue_trace(request.headers) +with sentry_sdk.start_span(name="handle-request"): + ... + +# Propagate to downstream services +traceparent = sentry_sdk.get_traceparent() +baggage = sentry_sdk.get_baggage() + +# Start a fresh trace +sentry_sdk.new_trace() +with sentry_sdk.start_span(name="new-operation"): + ... +``` + +### Filtering Configuration + +```js {tabTitle:TypeScript} +Sentry.init({ + ignoreSpans: [ + 'GET /about', + /api\/\d+/, + { + name: /healthz?/, + attributes: { + 'http.method': 'GET', + } + }, + { + attributes: { + 'http.method': /GET \/api\/.*/, + } + }, + ] +}) +``` + +```python {tabTitle:Python} +sentry_sdk.init( + ignore_spans=[ + "GET /about", + r"api\/\d+", + { + "name": r"healthz?", + "attributes": { + "http.method": "GET", + } + }, + ], +) +``` + +### Wire Format — Envelope Payload + +```json +{ + "version": 2, + "ingest_settings": { + "infer_ip": "auto", + "infer_user_agent": "auto" + }, + "items": [ + { + "trace_id": "6cf173d587eb48568a9b2e12dcfbea52", + "span_id": "438f40bd3b4a41ee", + "name": "GET /users", + "status": "ok", + "is_segment": true, + "start_timestamp": 1742921669.158209, + "end_timestamp": 1742921669.180536, + "attributes": { + "sentry.release": { + "type": "string", + "value": "1.0.0" + }, + "sentry.environment": { + "type": "string", + "value": "production" + }, + "sentry.platform": { + "type": "string", + "value": "php" + }, + "sentry.sdk.name": { + "type": "string", + "value": "sentry.php" + }, + "sentry.sdk.version": { + "type": "string", + "value": "4.10.0" + }, + "sentry.origin": { + "type": "string", + "value": "auto" + }, + "http.response.status_code": { + "type": "integer", + "value": 200 + } + }, + "links": [ + { + "span_id": "6c71fc6b09b8b716", + "trace_id": "627a2885119dcc8184fae7eef09438cb", + "sampled": true, + "attributes": { + "sentry.link.type": { + "type": "string", + "value": "previous_trace" + } + } + } + ] + }, + { + "trace_id": "6cf173d587eb48568a9b2e12dcfbea52", + "parent_span_id": "438f40bd3b4a41ee", + "span_id": "f1196292f76e45c0", + "name": "app.handle", + "status": "ok", + "is_segment": false, + "start_timestamp": 1742921669.178306, + "end_timestamp": 1742921669.180484, + "attributes": { + "sentry.origin": { + "type": "string", + "value": "auto" + } + } + } + ] +} +``` + +--- + +## Changelog + +