From a0a3e2187d9c99f735705faa4756d27d367e09d4 Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Wed, 25 Jun 2025 09:49:09 +0200 Subject: [PATCH 01/10] Add attribute for distinguishing span parent origin --- docs/otel/sdk-metrics.md | 11 +++++++++++ docs/registry/attributes/otel.md | 11 +++++++++++ model/otel/metrics.yaml | 1 + model/otel/registry.yaml | 17 +++++++++++++++++ 4 files changed, 40 insertions(+) diff --git a/docs/otel/sdk-metrics.md b/docs/otel/sdk-metrics.md index 9591d512a6..e878b2627f 100644 --- a/docs/otel/sdk-metrics.md +++ b/docs/otel/sdk-metrics.md @@ -95,10 +95,21 @@ For spans with `recording=false`: If implementations decide to record this metri | 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 | `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() 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() 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 | diff --git a/docs/registry/attributes/otel.md b/docs/registry/attributes/otel.md index 1a476ccb6a..16e0ccd3a2 100644 --- a/docs/registry/attributes/otel.md +++ b/docs/registry/attributes/otel.md @@ -14,12 +14,23 @@ Attributes reserved for OpenTelemetry | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| +| `otel.span.parent.origin` | string | Determines whether the span has a parent span, and if so, whether it is a remote parent | `NONE`; `LOCAL`; `REMOTE` | ![Development](https://img.shields.io/badge/-development-blue) | | `otel.span.sampling_result` | string | The result value of the sampler for this span | `DROP`; `RECORD_ONLY`; `RECORD_AND_SAMPLE` | ![Development](https://img.shields.io/badge/-development-blue) | | `otel.status_code` | 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) | | `otel.status_description` | 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() 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() 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 | diff --git a/model/otel/metrics.yaml b/model/otel/metrics.yaml index ecb7d10d89..4ac20aed1b 100644 --- a/model/otel/metrics.yaml +++ b/model/otel/metrics.yaml @@ -24,6 +24,7 @@ groups: For spans with `recording=false`: If implementations decide to record this metric, they MUST also record `otel.sdk.span.live`. attributes: - ref: otel.span.sampling_result + - ref: otel.span.parent.origin - id: metric.otel.sdk.processor.span.queue.size type: metric diff --git a/model/otel/registry.yaml b/model/otel/registry.yaml index f7e7fd7f1f..101cca9c62 100644 --- a/model/otel/registry.yaml +++ b/model/otel/registry.yaml @@ -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() is false + stability: development + - id: remote + value: REMOTE + brief: The span has a parent and the parent's span context isRemote() is true + stability: development + brief: "Determines whether the span has a parent span, and if so, whether it is a remote parent" + stability: development - id: registry.otel.scope type: attribute_group display_name: OTel Scope Attributes From 303f37bc04f2f7b11e9b7df4d4cc176cc0af79f3 Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Wed, 25 Jun 2025 10:21:32 +0200 Subject: [PATCH 02/10] Require recording span.ended metric --- docs/otel/sdk-metrics.md | 7 +++++-- model/otel/metrics.yaml | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/otel/sdk-metrics.md b/docs/otel/sdk-metrics.md index e878b2627f..63421b6eaf 100644 --- a/docs/otel/sdk-metrics.md +++ b/docs/otel/sdk-metrics.md @@ -54,7 +54,8 @@ This metric is [recommended][MetricRecommended]. | `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`. +For spans with `recording=false`: Implementations MAY omit recording `otel.sdk.span.live` (e.g. for performance or simplicity reasons). +In that case they MUST record `otel.sdk.span.ended` on span start for those spans instead. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| @@ -91,7 +92,9 @@ This metric is [recommended][MetricRecommended]. | `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) | | **[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`. +For spans with `recording=false`: If implementations decide to not record `otel.sdk.span.live`, they MUST record `otel.sdk.span.ended` on span start for those spans instead. +In other words, for spans with `recording=false` implementations may treat them as ended directly after they are started from a metrics perspective. +This ensures that `otel.sdk.span.ended` is guaranteed to provide insights about the total span counts and sampling rates, even if spans are not recorded. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| diff --git a/model/otel/metrics.yaml b/model/otel/metrics.yaml index 4ac20aed1b..856ffe0287 100644 --- a/model/otel/metrics.yaml +++ b/model/otel/metrics.yaml @@ -8,7 +8,8 @@ groups: 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`. + For spans with `recording=false`: Implementations MAY omit recording `otel.sdk.span.live` (e.g. for performance or simplicity reasons). + In that case they MUST record `otel.sdk.span.ended` on span start for those spans instead. attributes: - ref: otel.span.sampling_result @@ -21,7 +22,9 @@ groups: 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`. + For spans with `recording=false`: If implementations decide to not record `otel.sdk.span.live`, they MUST record `otel.sdk.span.ended` on span start for those spans instead. + In other words, for spans with `recording=false` implementations may treat them as ended directly after they are started from a metrics perspective. + This ensures that `otel.sdk.span.ended` is guaranteed to provide insights about the total span counts and sampling rates, even if spans are not recorded. attributes: - ref: otel.span.sampling_result - ref: otel.span.parent.origin From a96b32ba685ae42113e7f0a572c8b3130adec491 Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Wed, 25 Jun 2025 10:32:16 +0200 Subject: [PATCH 03/10] Add changelog --- .chloggen/span-ended-metric-improvements.yaml | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .chloggen/span-ended-metric-improvements.yaml diff --git a/.chloggen/span-ended-metric-improvements.yaml b/.chloggen/span-ended-metric-improvements.yaml new file mode 100644 index 0000000000..37324bedc1 --- /dev/null +++ b/.chloggen/span-ended-metric-improvements.yaml @@ -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: Ensure that the `otel.sdk.span.ended` is collected even for non-recording spans 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: From 084c342a25557b2c9d4d5761c9ff58567bd5c29a Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Mon, 30 Jun 2025 09:45:05 +0200 Subject: [PATCH 04/10] Review fix: add link to isRemote API call --- docs/otel/sdk-metrics.md | 2 +- docs/registry/attributes/otel.md | 2 +- model/otel/registry.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/otel/sdk-metrics.md b/docs/otel/sdk-metrics.md index 63421b6eaf..ed9e8c35e7 100644 --- a/docs/otel/sdk-metrics.md +++ b/docs/otel/sdk-metrics.md @@ -98,7 +98,7 @@ This ensures that `otel.sdk.span.ended` is guaranteed to provide insights about | 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 | `NONE`; `LOCAL`; `REMOTE` | `Recommended` | ![Development](https://img.shields.io/badge/-development-blue) | +| [`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) | --- diff --git a/docs/registry/attributes/otel.md b/docs/registry/attributes/otel.md index 16e0ccd3a2..d46195c6cb 100644 --- a/docs/registry/attributes/otel.md +++ b/docs/registry/attributes/otel.md @@ -14,7 +14,7 @@ Attributes reserved for OpenTelemetry | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| -| `otel.span.parent.origin` | string | Determines whether the span has a parent span, and if so, whether it is a remote parent | `NONE`; `LOCAL`; `REMOTE` | ![Development](https://img.shields.io/badge/-development-blue) | +| `otel.span.parent.origin` | 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) | | `otel.span.sampling_result` | string | The result value of the sampler for this span | `DROP`; `RECORD_ONLY`; `RECORD_AND_SAMPLE` | ![Development](https://img.shields.io/badge/-development-blue) | | `otel.status_code` | 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) | | `otel.status_description` | string | Description of the Status if it has a value, otherwise not set. | `resource not found` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | diff --git a/model/otel/registry.yaml b/model/otel/registry.yaml index 101cca9c62..ef3c880b2f 100644 --- a/model/otel/registry.yaml +++ b/model/otel/registry.yaml @@ -54,7 +54,7 @@ groups: value: REMOTE brief: The span has a parent and the parent's span context isRemote() is true stability: development - brief: "Determines whether the span has a parent span, and if so, whether it is a remote parent" + 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 From f2894fba01966aa521ba8618a91f7cff6a09ed23 Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Mon, 30 Jun 2025 09:47:20 +0200 Subject: [PATCH 05/10] More links --- docs/otel/sdk-metrics.md | 4 ++-- docs/registry/attributes/otel.md | 4 ++-- model/otel/registry.yaml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/otel/sdk-metrics.md b/docs/otel/sdk-metrics.md index ed9e8c35e7..2e09537802 100644 --- a/docs/otel/sdk-metrics.md +++ b/docs/otel/sdk-metrics.md @@ -107,9 +107,9 @@ This ensures that `otel.sdk.span.ended` is guaranteed to provide insights about | Value | Description | Stability | |---|---|---| -| `LOCAL` | The span has a parent and the parent's span context isRemote() is false | ![Development](https://img.shields.io/badge/-development-blue) | +| `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() is true | ![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) | --- diff --git a/docs/registry/attributes/otel.md b/docs/registry/attributes/otel.md index d46195c6cb..c0c3ee654a 100644 --- a/docs/registry/attributes/otel.md +++ b/docs/registry/attributes/otel.md @@ -25,9 +25,9 @@ Attributes reserved for OpenTelemetry | Value | Description | Stability | |---|---|---| -| `LOCAL` | The span has a parent and the parent's span context isRemote() is false | ![Development](https://img.shields.io/badge/-development-blue) | +| `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() is true | ![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) | --- diff --git a/model/otel/registry.yaml b/model/otel/registry.yaml index ef3c880b2f..cccca3f14b 100644 --- a/model/otel/registry.yaml +++ b/model/otel/registry.yaml @@ -48,11 +48,11 @@ groups: stability: development - id: local value: LOCAL - brief: The span has a parent and the parent's span context isRemote() is false + 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() is true + 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 From c1a4becc708bd73f7ef73eec3efeba46a2f54fc4 Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Tue, 1 Jul 2025 09:05:14 +0200 Subject: [PATCH 06/10] Replace span.ended with span.started metric --- docs/otel/sdk-metrics.md | 19 ++++++------------- model/otel/deprecated/metrics-deprecated.yaml | 9 +++++++++ model/otel/metrics.yaml | 17 +++++------------ 3 files changed, 20 insertions(+), 25 deletions(-) diff --git a/docs/otel/sdk-metrics.md b/docs/otel/sdk-metrics.md index 2e09537802..20599997b7 100644 --- a/docs/otel/sdk-metrics.md +++ b/docs/otel/sdk-metrics.md @@ -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) @@ -51,11 +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`: Implementations MAY omit recording `otel.sdk.span.live` (e.g. for performance or simplicity reasons). -In that case they MUST record `otel.sdk.span.ended` on span start for those spans instead. +| `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 | |---|---|---|---|---|---| @@ -76,11 +72,11 @@ In that case they MUST record `otel.sdk.span.ended` on span start for those span -### Metric: `otel.sdk.span.ended` +### Metric: `otel.sdk.span.started` This metric is [recommended][MetricRecommended]. - + @@ -89,12 +85,9 @@ 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 not record `otel.sdk.span.live`, they MUST record `otel.sdk.span.ended` on span start for those spans instead. -In other words, for spans with `recording=false` implementations may treat them as ended directly after they are started from a metrics perspective. -This ensures that `otel.sdk.span.ended` is guaranteed to provide insights about the total span counts and sampling rates, even if spans are not recorded. +**[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 | |---|---|---|---|---|---| diff --git a/model/otel/deprecated/metrics-deprecated.yaml b/model/otel/deprecated/metrics-deprecated.yaml index 4c547e605f..33d9a510f6 100644 --- a/model/otel/deprecated/metrics-deprecated.yaml +++ b/model/otel/deprecated/metrics-deprecated.yaml @@ -49,3 +49,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}" diff --git a/model/otel/metrics.yaml b/model/otel/metrics.yaml index 856ffe0287..0226f928aa 100644 --- a/model/otel/metrics.yaml +++ b/model/otel/metrics.yaml @@ -3,28 +3,21 @@ 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`: Implementations MAY omit recording `otel.sdk.span.live` (e.g. for performance or simplicity reasons). - In that case they MUST record `otel.sdk.span.ended` on span start for those spans instead. 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 not record `otel.sdk.span.live`, they MUST record `otel.sdk.span.ended` on span start for those spans instead. - In other words, for spans with `recording=false` implementations may treat them as ended directly after they are started from a metrics perspective. - This ensures that `otel.sdk.span.ended` is guaranteed to provide insights about the total span counts and sampling rates, even if spans are not recorded. + Implementations MUST record this metric for all spans, even for non-recording ones. attributes: - ref: otel.span.sampling_result - ref: otel.span.parent.origin From 407641c83132c1aebc16da43e8e2ae532a0e047e Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Tue, 1 Jul 2025 09:14:18 +0200 Subject: [PATCH 07/10] Update span.ended.count deprecation --- model/otel/deprecated/metrics-deprecated.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/model/otel/deprecated/metrics-deprecated.yaml b/model/otel/deprecated/metrics-deprecated.yaml index 33d9a510f6..f92db89d12 100644 --- a/model/otel/deprecated/metrics-deprecated.yaml +++ b/model/otel/deprecated/metrics-deprecated.yaml @@ -24,9 +24,8 @@ groups: metric_name: otel.sdk.processor.span.processed.count stability: development deprecated: - reason: renamed - renamed_to: otel.sdk.processor.span.processed - brief: "Deprecated, use `otel.sdk.processor.span.processed` instead." + reason: obsoleted + brief: "Use `otel.sdk.span.started` minus `otel.sdk.span.live` to derive this value." instrument: updowncounter unit: "{span}" - id: metric.otel.sdk.exporter.span.inflight.count From 53763a2df55f39728b9b4feefc1e19daa1670d0a Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Tue, 1 Jul 2025 09:17:51 +0200 Subject: [PATCH 08/10] Fix deprecations, second attempt --- model/otel/deprecated/metrics-deprecated.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/model/otel/deprecated/metrics-deprecated.yaml b/model/otel/deprecated/metrics-deprecated.yaml index f92db89d12..3cfeeb0d15 100644 --- a/model/otel/deprecated/metrics-deprecated.yaml +++ b/model/otel/deprecated/metrics-deprecated.yaml @@ -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 @@ -24,8 +23,9 @@ groups: metric_name: otel.sdk.processor.span.processed.count stability: development deprecated: - reason: obsoleted - brief: "Use `otel.sdk.span.started` minus `otel.sdk.span.live` to derive this value." + reason: renamed + renamed_to: otel.sdk.processor.span.processed + brief: "Deprecated, use `otel.sdk.processor.span.processed` instead." instrument: updowncounter unit: "{span}" - id: metric.otel.sdk.exporter.span.inflight.count From 4df81758162f5fd8f4541605a5de49d9b3d8638d Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Tue, 1 Jul 2025 09:59:54 +0200 Subject: [PATCH 09/10] Update changelog --- ...ric-improvements.yaml => span-ended-metric-replacement.yaml} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename .chloggen/{span-ended-metric-improvements.yaml => span-ended-metric-replacement.yaml} (86%) diff --git a/.chloggen/span-ended-metric-improvements.yaml b/.chloggen/span-ended-metric-replacement.yaml similarity index 86% rename from .chloggen/span-ended-metric-improvements.yaml rename to .chloggen/span-ended-metric-replacement.yaml index 37324bedc1..e9ac7dbd83 100644 --- a/.chloggen/span-ended-metric-improvements.yaml +++ b/.chloggen/span-ended-metric-replacement.yaml @@ -10,7 +10,7 @@ change_type: 'enhancement' component: 'otel' # A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: Ensure that the `otel.sdk.span.ended` is collected even for non-recording spans and allow differentiation based on the parent span origin +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. From d18b55b20f19dc03a4ddbdeb3033a340a13e3ef6 Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Wed, 2 Jul 2025 09:54:47 +0200 Subject: [PATCH 10/10] Remove SCREAMING_CASE --- docs/otel/sdk-metrics.md | 8 ++++---- docs/registry/attributes/otel.md | 8 ++++---- model/otel/registry.yaml | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/otel/sdk-metrics.md b/docs/otel/sdk-metrics.md index 20599997b7..ec9e913a53 100644 --- a/docs/otel/sdk-metrics.md +++ b/docs/otel/sdk-metrics.md @@ -91,7 +91,7 @@ This metric is [recommended][MetricRecommended]. | 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.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) | --- @@ -100,9 +100,9 @@ This metric is [recommended][MetricRecommended]. | 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) | +| `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) | --- diff --git a/docs/registry/attributes/otel.md b/docs/registry/attributes/otel.md index c0c3ee654a..cf9ec65e71 100644 --- a/docs/registry/attributes/otel.md +++ b/docs/registry/attributes/otel.md @@ -14,7 +14,7 @@ Attributes reserved for OpenTelemetry | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| -| `otel.span.parent.origin` | 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) | +| `otel.span.parent.origin` | 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) | | `otel.span.sampling_result` | string | The result value of the sampler for this span | `DROP`; `RECORD_ONLY`; `RECORD_AND_SAMPLE` | ![Development](https://img.shields.io/badge/-development-blue) | | `otel.status_code` | 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) | | `otel.status_description` | string | Description of the Status if it has a value, otherwise not set. | `resource not found` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | @@ -25,9 +25,9 @@ Attributes reserved for OpenTelemetry | 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) | +| `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) | --- diff --git a/model/otel/registry.yaml b/model/otel/registry.yaml index cccca3f14b..2d3fed96e8 100644 --- a/model/otel/registry.yaml +++ b/model/otel/registry.yaml @@ -43,15 +43,15 @@ groups: type: members: - id: none - value: NONE + value: none brief: 'The span does not have a parent, it is a root span' stability: development - id: local - value: 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 + 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)"