Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
3eeba4c
add docs
pellared Jul 15, 2025
5fe199b
Refine docs
pellared Jul 15, 2025
2212cb2
Merge branch 'main' into span-metrics
pellared Jul 16, 2025
16df7b8
Move experimental docs to x/internal
pellared Jul 16, 2025
e6a3029
improve docs
pellared Jul 16, 2025
45aaace
update header
pellared Jul 16, 2025
7c1ea5c
fix link
pellared Jul 16, 2025
547a989
draft implementation
pellared Jul 16, 2025
bb6b8f8
add TestSelfObservabilty and fix implementation
pellared Jul 16, 2025
2fd1368
Add attributes
pellared Jul 16, 2025
25894d6
Add changelog entry
pellared Jul 16, 2025
418297e
lint
pellared Jul 16, 2025
6b33d72
Update TODO comments
pellared Jul 16, 2025
d9105c0
Merge branch 'main' into span-metrics
pellared Jul 17, 2025
3d132c7
go mod tidy
pellared Jul 17, 2025
713a3e7
Bump to semconv/v1.36.0
pellared Jul 17, 2025
8cd9767
refactor initSelfObservability
pellared Jul 17, 2025
6304e1d
refactor attr creation
pellared Jul 17, 2025
3fa8aa5
add otel.span.parent.origin attribute
pellared Jul 17, 2025
455060a
Add test cases
pellared Jul 17, 2025
89d3a8d
refactor test
pellared Jul 17, 2025
b9d533a
Add RemoteParentSpan case
pellared Jul 17, 2025
21735b7
Add LocalParentSpan test case
pellared Jul 17, 2025
9975391
tidy tests
pellared Jul 17, 2025
ab3e2eb
Add OnlyRecordingSpan test case
pellared Jul 17, 2025
e729681
refactor TestRecordOnlySampler
pellared Jul 17, 2025
c40a561
Redo the docs
pellared Jul 17, 2025
24b4f8e
nolint
pellared Jul 17, 2025
90885b9
Merge branch 'main' into span-metrics
pellared Jul 17, 2025
f3740e6
markdownlint fix
pellared Jul 17, 2025
4b37175
Merge branch 'main' into span-metrics
pellared Jul 21, 2025
fcef2ac
Merge branch 'main' into span-metrics
pellared Jul 21, 2025
76001a3
Merge branch 'main' into span-metrics
pellared Jul 21, 2025
5e44856
Update sdk/trace/internal/x/README.md
pellared Jul 21, 2025
afee3cc
Merge branch 'main' into span-metrics
pellared Jul 22, 2025
ad13ce9
refactor: reuse x.SelfObservability
pellared Jul 22, 2025
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- The `go.opentelemetry.io/otel/semconv/v1.36.0` package.
The package contains semantic conventions from the `v1.36.0` version of the OpenTelemetry Semantic Conventions.
See the [migration documentation](./semconv/v1.36.0/MIGRATION.md) for information on how to upgrade from `go.opentelemetry.io/otel/semconv/v1.34.0.`(#7032)
- Add experimental self-observability span metrics in `go.opentelemetry.io/otel/sdk/trace`.
Check the `go.opentelemetry.io/otel/sdk/trace/internal/x` package documentation for more information. (#7027)

### Changed

Expand Down
2 changes: 2 additions & 0 deletions exporters/otlp/otlplog/otlploggrpc/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,5 @@ replace go.opentelemetry.io/otel/trace => ../../../../trace
replace go.opentelemetry.io/otel/metric => ../../../../metric

replace go.opentelemetry.io/otel/sdk/log/logtest => ../../../../sdk/log/logtest

replace go.opentelemetry.io/otel/sdk/metric => ../../../../sdk/metric
2 changes: 0 additions & 2 deletions exporters/otlp/otlplog/otlploggrpc/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os=
go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo=
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
Expand Down
2 changes: 2 additions & 0 deletions exporters/otlp/otlplog/otlploghttp/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,5 @@ replace go.opentelemetry.io/otel/sdk => ../../../../sdk
replace go.opentelemetry.io/otel/metric => ../../../../metric

replace go.opentelemetry.io/otel/log => ../../../../log

replace go.opentelemetry.io/otel/sdk/metric => ../../../../sdk/metric
2 changes: 0 additions & 2 deletions exporters/otlp/otlplog/otlploghttp/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os=
go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo=
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
Expand Down
2 changes: 2 additions & 0 deletions exporters/otlp/otlptrace/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,5 @@ replace go.opentelemetry.io/otel/sdk => ../../../sdk
replace go.opentelemetry.io/otel/trace => ../../../trace

replace go.opentelemetry.io/otel/metric => ../../../metric

replace go.opentelemetry.io/otel/sdk/metric => ../../../sdk/metric
2 changes: 2 additions & 0 deletions exporters/otlp/otlptrace/otlptracegrpc/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,5 @@ replace go.opentelemetry.io/otel/exporters/otlp/otlptrace => ../
replace go.opentelemetry.io/otel/trace => ../../../../trace

replace go.opentelemetry.io/otel/metric => ../../../../metric

replace go.opentelemetry.io/otel/sdk/metric => ../../../../sdk/metric
2 changes: 0 additions & 2 deletions exporters/otlp/otlptrace/otlptracegrpc/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os=
go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
Expand Down
2 changes: 2 additions & 0 deletions exporters/otlp/otlptrace/otlptracehttp/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,5 @@ replace go.opentelemetry.io/otel/sdk => ../../../../sdk
replace go.opentelemetry.io/otel/trace => ../../../../trace

replace go.opentelemetry.io/otel/metric => ../../../../metric

replace go.opentelemetry.io/otel/sdk/metric => ../../../../sdk/metric
2 changes: 0 additions & 2 deletions exporters/otlp/otlptrace/otlptracehttp/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os=
go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
Expand Down
2 changes: 2 additions & 0 deletions exporters/stdout/stdoutlog/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,5 @@ replace go.opentelemetry.io/otel/trace => ../../../trace
replace go.opentelemetry.io/otel/sdk => ../../../sdk

replace go.opentelemetry.io/otel/metric => ../../../metric

replace go.opentelemetry.io/otel/sdk/metric => ../../../sdk/metric
2 changes: 2 additions & 0 deletions exporters/stdout/stdouttrace/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@ require (
replace go.opentelemetry.io/otel/trace => ../../../trace

replace go.opentelemetry.io/otel/metric => ../../../metric

replace go.opentelemetry.io/otel/sdk/metric => ../../../sdk/metric
2 changes: 2 additions & 0 deletions exporters/zipkin/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,5 @@ replace go.opentelemetry.io/otel => ../..
replace go.opentelemetry.io/otel/sdk => ../../sdk

replace go.opentelemetry.io/otel/metric => ../../metric

replace go.opentelemetry.io/otel/sdk/metric => ../../sdk/metric
5 changes: 4 additions & 1 deletion sdk/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ require (
github.com/google/uuid v1.6.0
github.com/stretchr/testify v1.10.0
go.opentelemetry.io/otel v1.37.0
go.opentelemetry.io/otel/metric v1.37.0
go.opentelemetry.io/otel/sdk/metric v1.37.0
go.opentelemetry.io/otel/trace v1.37.0
go.uber.org/goleak v1.3.0
golang.org/x/sys v0.34.0
Expand All @@ -20,10 +22,11 @@ require (
github.com/go-logr/stdr v1.2.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/otel/metric v1.37.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

replace go.opentelemetry.io/otel/trace => ../trace

replace go.opentelemetry.io/otel/metric => ../metric

replace go.opentelemetry.io/otel/sdk/metric => ./metric
2 changes: 2 additions & 0 deletions sdk/log/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,5 @@ replace go.opentelemetry.io/otel/sdk => ../
replace go.opentelemetry.io/otel/log => ../../log

replace go.opentelemetry.io/otel => ../..

replace go.opentelemetry.io/otel/sdk/metric => ../metric
2 changes: 2 additions & 0 deletions sdk/log/logtest/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,5 @@ replace go.opentelemetry.io/otel/sdk/log => ../
replace go.opentelemetry.io/otel/log => ../../../log

replace go.opentelemetry.io/otel => ../../..

replace go.opentelemetry.io/otel/sdk/metric => ../../metric
3 changes: 3 additions & 0 deletions sdk/trace/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,8 @@ Package trace contains support for OpenTelemetry distributed tracing.

The following assumes a basic familiarity with OpenTelemetry concepts.
See https://opentelemetry.io.

See [go.opentelemetry.io/otel/sdk/trace/internal/x] for information about
the experimental features.
*/
package trace // import "go.opentelemetry.io/otel/sdk/trace"
35 changes: 35 additions & 0 deletions sdk/trace/internal/x/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Experimental Features

The metric SDK contains features that have not yet stabilized in the OpenTelemetry specification.
These features are added to the OpenTelemetry Go metric SDK prior to stabilization in the specification so that users can start experimenting with them and provide feedback.

These feature may change in backwards incompatible ways as feedback is applied.
See the [Compatibility and Stability](#compatibility-and-stability) section for more information.

## Features

- [Self-Observability](#self-observability)

### Self-Observability

The SDK provides a self-observability feature that allows you to monitor the SDK itself.

To opt-in, set the environment variable `OTEL_GO_X_SELF_OBSERVABILITY` to `true`.

When enabled, the SDK will create the following metrics using the global `MeterProvider`:

- `otel.sdk.span.live`
- `otel.sdk.span.started`

Please see the [Semantic conventions for OpenTelemetry SDK metrics] documentation for more details on these metrics.

[Semantic conventions for OpenTelemetry SDK metrics]: https://github.com/open-telemetry/semantic-conventions/blob/v1.36.0/docs/otel/sdk-metrics.md

## Compatibility and Stability

Experimental features do not fall within the scope of the OpenTelemetry Go versioning and stability [policy](../../../../VERSIONING.md).
These features may be removed or modified in successive version releases, including patch versions.

When an experimental feature is promoted to a stable feature, a migration path will be included in the changelog entry of the release.
There is no guarantee that any environment variable feature flags that enabled the experimental feature will be supported by the stable version.
If they are supported, they may be accompanied with a deprecation notice stating a timeline for the removal of that support.
63 changes: 63 additions & 0 deletions sdk/trace/internal/x/x.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

// Package x documents experimental features for [go.opentelemetry.io/otel/sdk/trace].
package x // import "go.opentelemetry.io/otel/sdk/trace/internal/x"

import (
"os"
"strings"
)

// SelfObservability is an experimental feature flag that determines if SDK
// self-observability metrics are enabled.
//
// To enable this feature set the OTEL_GO_X_SELF_OBSERVABILITY environment variable
// to the case-insensitive string value of "true" (i.e. "True" and "TRUE"
// will also enable this).
var SelfObservability = newFeature("SELF_OBSERVABILITY", func(v string) (string, bool) {
if strings.ToLower(v) == "true" {
return v, true
}
return "", false
})

// Feature is an experimental feature control flag. It provides a uniform way
// to interact with these feature flags and parse their values.
type Feature[T any] struct {
key string
parse func(v string) (T, bool)
}

func newFeature[T any](suffix string, parse func(string) (T, bool)) Feature[T] {
const envKeyRoot = "OTEL_GO_X_"
return Feature[T]{
key: envKeyRoot + suffix,
parse: parse,
}
}

// Key returns the environment variable key that needs to be set to enable the
// feature.
func (f Feature[T]) Key() string { return f.key }

// Lookup returns the user configured value for the feature and true if the
// user has enabled the feature. Otherwise, if the feature is not enabled, a
// zero-value and false are returned.
func (f Feature[T]) Lookup() (v T, ok bool) {
// https://github.com/open-telemetry/opentelemetry-specification/blob/62effed618589a0bec416a87e559c0a9d96289bb/specification/configuration/sdk-environment-variables.md#parsing-empty-value
//
// > The SDK MUST interpret an empty value of an environment variable the
// > same way as when the variable is unset.
vRaw := os.Getenv(f.key)
if vRaw == "" {
return v, ok
}
return f.parse(vRaw)
}

// Enabled returns if the feature is enabled.
func (f Feature[T]) Enabled() bool {
_, ok := f.Lookup()
return ok
}
59 changes: 59 additions & 0 deletions sdk/trace/internal/x/x_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

package x

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestSelfObservability(t *testing.T) {
const key = "OTEL_GO_X_SELF_OBSERVABILITY"
require.Equal(t, key, SelfObservability.Key())

t.Run("100", run(setenv(key, "100"), assertDisabled(SelfObservability)))
t.Run("true", run(setenv(key, "true"), assertEnabled(SelfObservability, "true")))
t.Run("True", run(setenv(key, "True"), assertEnabled(SelfObservability, "True")))
t.Run("false", run(setenv(key, "false"), assertDisabled(SelfObservability)))
t.Run("empty", run(assertDisabled(SelfObservability)))
}

func run(steps ...func(*testing.T)) func(*testing.T) {
return func(t *testing.T) {
t.Helper()
for _, step := range steps {
step(t)
}
}
}

func setenv(k, v string) func(t *testing.T) { //nolint:unparam // This is a reusable test utility function.
return func(t *testing.T) { t.Setenv(k, v) }
}

func assertEnabled[T any](f Feature[T], want T) func(*testing.T) {
return func(t *testing.T) {
t.Helper()
assert.True(t, f.Enabled(), "not enabled")

v, ok := f.Lookup()
assert.True(t, ok, "Lookup state")
assert.Equal(t, want, v, "Lookup value")
}
}

func assertDisabled[T any](f Feature[T]) func(*testing.T) {
var zero T
return func(t *testing.T) {
t.Helper()

assert.False(t, f.Enabled(), "enabled")

v, ok := f.Lookup()
assert.False(t, ok, "Lookup state")
assert.Equal(t, zero, v, "Lookup value")
}
}
1 change: 1 addition & 0 deletions sdk/trace/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ func (p *TracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.T
provider: p,
instrumentationScope: is,
}
t.initSelfObservability()
p.namedTracer[is] = t
}
return t, ok
Expand Down
19 changes: 18 additions & 1 deletion sdk/trace/span.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ import (
"go.opentelemetry.io/otel/internal/global"
"go.opentelemetry.io/otel/sdk/instrumentation"
"go.opentelemetry.io/otel/sdk/resource"
semconv "go.opentelemetry.io/otel/semconv/v1.34.0"
semconv "go.opentelemetry.io/otel/semconv/v1.36.0"
"go.opentelemetry.io/otel/semconv/v1.36.0/otelconv"
"go.opentelemetry.io/otel/trace"
"go.opentelemetry.io/otel/trace/embedded"
)
Expand Down Expand Up @@ -496,6 +497,22 @@ func (s *recordingSpan) End(options ...trace.SpanEndOption) {
}
s.mu.Unlock()

defer func() {
if s.tracer.selfObservabilityEnabled {
// Determine the sampling result and create the corresponding attribute.
var attrSamplingResult attribute.KeyValue
if s.spanContext.IsSampled() {
attrSamplingResult = s.tracer.spanLiveMetric.AttrSpanSamplingResult(
otelconv.SpanSamplingResultRecordAndSample,
)
} else {
attrSamplingResult = s.tracer.spanLiveMetric.AttrSpanSamplingResult(otelconv.SpanSamplingResultRecordOnly)
}

s.tracer.spanLiveMetric.Add(context.Background(), -1, attrSamplingResult)
}
}()

sps := s.tracer.provider.getSpanProcessors()
if len(sps) == 0 {
return
Expand Down
Loading
Loading