Skip to content

Replace otel.sdk.span.ended metric with improved span.started metric #2431

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jul 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .chloggen/span-ended-metric-replacement.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Use this changelog template to create an entry for release notes.
#
# If your change doesn't affect end users you should instead start
# your pull request title with [chore] or use the "Skip Changelog" label.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: 'enhancement'

# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db)
component: 'otel'

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Replaces `otel.sdk.span.ended` with `otel.sdk.span.started` and allow differentiation based on the parent span origin

# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
# The values here must be integers.
issues: [2431]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext:
27 changes: 17 additions & 10 deletions docs/otel/sdk-metrics.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ This document describes metrics emitted by the OpenTelemetry SDK components them

- [Span metrics](#span-metrics)
- [Metric: `otel.sdk.span.live`](#metric-otelsdkspanlive)
- [Metric: `otel.sdk.span.ended`](#metric-otelsdkspanended)
- [Metric: `otel.sdk.span.started`](#metric-otelsdkspanstarted)
- [Metric: `otel.sdk.processor.span.queue.size`](#metric-otelsdkprocessorspanqueuesize)
- [Metric: `otel.sdk.processor.span.queue.capacity`](#metric-otelsdkprocessorspanqueuecapacity)
- [Metric: `otel.sdk.processor.span.processed`](#metric-otelsdkprocessorspanprocessed)
Expand Down Expand Up @@ -51,10 +51,7 @@ This metric is [recommended][MetricRecommended].

| Name | Instrument Type | Unit (UCUM) | Description | Stability | Entity Associations |
| -------- | --------------- | ----------- | -------------- | --------- | ------ |
| `otel.sdk.span.live` | UpDownCounter | `{span}` | The number of created spans for which the end operation has not been called yet [1] | ![Development](https://img.shields.io/badge/-development-blue) | |

**[1]:** For spans with `recording=true`: Implementations MUST record both `otel.sdk.span.live` and `otel.sdk.span.ended`.
For spans with `recording=false`: If implementations decide to record this metric, they MUST also record `otel.sdk.span.ended`.
| `otel.sdk.span.live` | UpDownCounter | `{span}` | The number of created spans with `recording=true` for which the end operation has not been called yet | ![Development](https://img.shields.io/badge/-development-blue) | |

| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
|---|---|---|---|---|---|
Expand All @@ -75,11 +72,11 @@ For spans with `recording=false`: If implementations decide to record this metri
<!-- END AUTOGENERATED TEXT -->
<!-- endsemconv -->

### Metric: `otel.sdk.span.ended`
### Metric: `otel.sdk.span.started`

This metric is [recommended][MetricRecommended].

<!-- semconv metric.otel.sdk.span.ended -->
<!-- semconv metric.otel.sdk.span.started -->
<!-- NOTE: THIS TEXT IS AUTOGENERATED. DO NOT EDIT BY HAND. -->
<!-- see templates/registry/markdown/snippet.md.j2 -->
<!-- prettier-ignore-start -->
Expand All @@ -88,17 +85,27 @@ This metric is [recommended][MetricRecommended].

| Name | Instrument Type | Unit (UCUM) | Description | Stability | Entity Associations |
| -------- | --------------- | ----------- | -------------- | --------- | ------ |
| `otel.sdk.span.ended` | Counter | `{span}` | The number of created spans for which the end operation was called [1] | ![Development](https://img.shields.io/badge/-development-blue) | |
| `otel.sdk.span.started` | Counter | `{span}` | The number of created spans [1] | ![Development](https://img.shields.io/badge/-development-blue) | |

**[1]:** For spans with `recording=true`: Implementations MUST record both `otel.sdk.span.live` and `otel.sdk.span.ended`.
For spans with `recording=false`: If implementations decide to record this metric, they MUST also record `otel.sdk.span.live`.
**[1]:** Implementations MUST record this metric for all spans, even for non-recording ones.

| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
|---|---|---|---|---|---|
| [`otel.span.parent.origin`](/docs/registry/attributes/otel.md) | string | Determines whether the span has a parent span, and if so, [whether it is a remote parent](https://opentelemetry.io/docs/specs/otel/trace/api/#isremote) | `none`; `local`; `remote` | `Recommended` | ![Development](https://img.shields.io/badge/-development-blue) |
| [`otel.span.sampling_result`](/docs/registry/attributes/otel.md) | string | The result value of the sampler for this span | `DROP`; `RECORD_ONLY`; `RECORD_AND_SAMPLE` | `Recommended` | ![Development](https://img.shields.io/badge/-development-blue) |

---

`otel.span.parent.origin` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.

| Value | Description | Stability |
|---|---|---|
| `local` | The span has a parent and the parent's span context [isRemote()](https://opentelemetry.io/docs/specs/otel/trace/api/#isremote) is false | ![Development](https://img.shields.io/badge/-development-blue) |
| `none` | The span does not have a parent, it is a root span | ![Development](https://img.shields.io/badge/-development-blue) |
| `remote` | The span has a parent and the parent's span context [isRemote()](https://opentelemetry.io/docs/specs/otel/trace/api/#isremote) is true | ![Development](https://img.shields.io/badge/-development-blue) |

---

`otel.span.sampling_result` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.

| Value | Description | Stability |
Expand Down
11 changes: 11 additions & 0 deletions docs/registry/attributes/otel.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,23 @@ Attributes reserved for OpenTelemetry

| Attribute | Type | Description | Examples | Stability |
|---|---|---|---|---|
| <a id="otel-span-parent-origin" href="#otel-span-parent-origin">`otel.span.parent.origin`</a> | string | Determines whether the span has a parent span, and if so, [whether it is a remote parent](https://opentelemetry.io/docs/specs/otel/trace/api/#isremote) | `none`; `local`; `remote` | ![Development](https://img.shields.io/badge/-development-blue) |
| <a id="otel-span-sampling-result" href="#otel-span-sampling-result">`otel.span.sampling_result`</a> | string | The result value of the sampler for this span | `DROP`; `RECORD_ONLY`; `RECORD_AND_SAMPLE` | ![Development](https://img.shields.io/badge/-development-blue) |
| <a id="otel-status-code" href="#otel-status-code">`otel.status_code`</a> | string | Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code is UNSET. | `OK`; `ERROR` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
| <a id="otel-status-description" href="#otel-status-description">`otel.status_description`</a> | string | Description of the Status if it has a value, otherwise not set. | `resource not found` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |

---

`otel.span.parent.origin` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.

| Value | Description | Stability |
|---|---|---|
| `local` | The span has a parent and the parent's span context [isRemote()](https://opentelemetry.io/docs/specs/otel/trace/api/#isremote) is false | ![Development](https://img.shields.io/badge/-development-blue) |
| `none` | The span does not have a parent, it is a root span | ![Development](https://img.shields.io/badge/-development-blue) |
| `remote` | The span has a parent and the parent's span context [isRemote()](https://opentelemetry.io/docs/specs/otel/trace/api/#isremote) is true | ![Development](https://img.shields.io/badge/-development-blue) |

---

`otel.span.sampling_result` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.

| Value | Description | Stability |
Expand Down
14 changes: 11 additions & 3 deletions model/otel/deprecated/metrics-deprecated.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ groups:
metric_name: otel.sdk.span.ended.count
stability: development
deprecated:
reason: renamed
renamed_to: otel.sdk.span.ended
brief: "Deprecated, use `otel.sdk.span.ended` instead."
reason: obsoleted
brief: "Use `otel.sdk.span.started` minus `otel.sdk.span.live` to derive this value."
instrument: counter
unit: "{span}"
- id: metric.otel.sdk.processor.span.processed.count
Expand Down Expand Up @@ -49,3 +48,12 @@ groups:
brief: "Deprecated, use `otel.sdk.exporter.span.exported` instead."
instrument: updowncounter
unit: "{span}"
- id: metric.otel.sdk.span.ended
type: metric
metric_name: otel.sdk.span.ended
stability: development
deprecated:
reason: obsoleted
brief: "Use `otel.sdk.span.started` minus `otel.sdk.span.live` to derive this value."
instrument: counter
unit: "{span}"
15 changes: 6 additions & 9 deletions model/otel/metrics.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,24 @@ groups:
type: metric
metric_name: otel.sdk.span.live
stability: development
brief: "The number of created spans for which the end operation has not been called yet"
brief: "The number of created spans with `recording=true` for which the end operation has not been called yet"
instrument: updowncounter
unit: "{span}"
note: |
For spans with `recording=true`: Implementations MUST record both `otel.sdk.span.live` and `otel.sdk.span.ended`.
For spans with `recording=false`: If implementations decide to record this metric, they MUST also record `otel.sdk.span.ended`.
attributes:
- ref: otel.span.sampling_result

- id: metric.otel.sdk.span.ended
- id: metric.otel.sdk.span.started
type: metric
metric_name: otel.sdk.span.ended
metric_name: otel.sdk.span.started
stability: development
brief: "The number of created spans for which the end operation was called"
brief: "The number of created spans"
instrument: counter
unit: "{span}"
note: |
For spans with `recording=true`: Implementations MUST record both `otel.sdk.span.live` and `otel.sdk.span.ended`.
For spans with `recording=false`: If implementations decide to record this metric, they MUST also record `otel.sdk.span.live`.
Implementations MUST record this metric for all spans, even for non-recording ones.
attributes:
- ref: otel.span.sampling_result
- ref: otel.span.parent.origin

- id: metric.otel.sdk.processor.span.queue.size
type: metric
Expand Down
17 changes: 17 additions & 0 deletions model/otel/registry.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,23 @@ groups:
stability: development
brief: "The result value of the sampler for this span"
stability: development
- id: otel.span.parent.origin
type:
members:
- id: none
value: none
brief: 'The span does not have a parent, it is a root span'
stability: development
- id: local
value: local
brief: The span has a parent and the parent's span context [isRemote()](https://opentelemetry.io/docs/specs/otel/trace/api/#isremote) is false
stability: development
- id: remote
value: remote
brief: The span has a parent and the parent's span context [isRemote()](https://opentelemetry.io/docs/specs/otel/trace/api/#isremote) is true
stability: development
brief: "Determines whether the span has a parent span, and if so, [whether it is a remote parent](https://opentelemetry.io/docs/specs/otel/trace/api/#isremote)"
stability: development
- id: registry.otel.scope
type: attribute_group
display_name: OTel Scope Attributes
Expand Down
Loading