Skip to content

Commit c718147

Browse files
authored
Merge branch 'main' into metrics_batching
2 parents 81059e8 + bffd2e0 commit c718147

20 files changed

Lines changed: 282 additions & 4 deletions

CONTRIBUTING.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,6 +1109,68 @@ func TestObservability(t *testing.T) {
11091109
Test order should not affect results.
11101110
Ensure that any global state (e.g. component ID counters) is reset between tests.
11111111

1112+
### Experimental Features
1113+
1114+
To support the development of new features in the specification, we use the following patterns to implement in-development features without adding new public artifacts in stable modules.
1115+
1116+
#### Experimental behavior with no API artifacts
1117+
1118+
Features that change behavior without changing the API (e.g., exemplar collection, auto-generation of identifiers) are implemented behind a feature gate.
1119+
The implementation resides in an `/internal/x` package and is activated through environment variables with the `OTEL_GO_X_` prefix (e.g., `OTEL_GO_X_OBSERVABILITY`).
1120+
The feature must be documented in a `README.md` file in the `/internal/x` package.
1121+
1122+
#### Experimental methods on SDK-only interfaces
1123+
1124+
Features that require new methods on SDK interfaces are defined as a new interface in an experimental module (e.g., `go.opentelemetry.io/otel/sdk/x`).
1125+
The SDK uses type assertions (without importing the unstable package) to check if passing types implement these experimental interfaces.
1126+
The SDK must not depend on the experimental module.
1127+
1128+
#### Experimental structs, functions, or interfaces
1129+
1130+
Features that don't need any changes to the existing stable package are implemented in an experimental module (e.g., `go.opentelemetry.io/otel/sdk/x`).
1131+
1132+
#### Experimental signals and components
1133+
1134+
New telemetry signals (e.g., Logs before stabilization) and components (e.g. bridges) are hosted in new, unstable modules (e.g., `go.opentelemetry.io/otel/log` before 1.0.0).
1135+
The package should have the final name it will use once stabilized (i.e. not `/x`), and is released at a v0.x.y version to indicate it is not stable.
1136+
Most new components are hosted in [opentelemetry-go-contrib](https://github.com/open-telemetry/opentelemetry-go-contrib).
1137+
1138+
#### Experimental options for API or SDK functions
1139+
1140+
Experimental Options functions are implemented in an experimental module (e.g., `go.opentelemetry.io/otel/sdk/x`).
1141+
The return type of the Option function must embed the option's type (e.g. `metric.InstrumentOption`), and have an `Experimental()` method to prevent the API from panicking when the option is used.
1142+
The SDK uses type assertions (without importing the unstable package) to check if passing types implement these experimental interfaces.
1143+
The SDK must not depend on the experimental module.
1144+
1145+
For example:
1146+
1147+
```go
1148+
type myOption struct {
1149+
// Embed the stable option type.
1150+
metric.InstrumentOption
1151+
value string
1152+
}
1153+
1154+
// Experimental prevents the API from panicking when the option is used.
1155+
func (o myOption) Experimental() {}
1156+
1157+
// The SDK can use type assertions to use this function.
1158+
func (o myOption) Value() string { return o.value }
1159+
1160+
func WithMyOption(value string) metric.InstrumentOption {
1161+
return myOption{value: value}
1162+
}
1163+
```
1164+
1165+
#### Not Supported
1166+
1167+
The following kinds of experimental features are **not currently supported** on stable interfaces:
1168+
1169+
- Experimental methods on API interfaces
1170+
- Experimental fields for API or SDK exported structs
1171+
1172+
In some cases forks or long-lived branches may be used for prototyping these features.
1173+
11121174
## Approvers and Maintainers
11131175

11141176
### Maintainers

bridge/opentracing/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ replace go.opentelemetry.io/otel/trace => ../../trace
88

99
require (
1010
github.com/opentracing-contrib/go-grpc v0.1.2
11-
github.com/opentracing-contrib/go-grpc/test v0.0.0-20260320052726-de6f1ccdd147
11+
github.com/opentracing-contrib/go-grpc/test v0.0.0-20260404024518-e5db98260807
1212
github.com/opentracing/opentracing-go v1.2.0
1313
github.com/stretchr/testify v1.11.1
1414
go.opentelemetry.io/otel v1.43.0

bridge/opentracing/go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
2020
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
2121
github.com/opentracing-contrib/go-grpc v0.1.2 h1:MP16Ozc59kqqwn1v18aQxpeGZhsBanJ2iurZYaQSZ+g=
2222
github.com/opentracing-contrib/go-grpc v0.1.2/go.mod h1:glU6rl1Fhfp9aXUHkE36K2mR4ht8vih0ekOVlWKEUHM=
23-
github.com/opentracing-contrib/go-grpc/test v0.0.0-20260320052726-de6f1ccdd147 h1:MtzxRkCJU9aGlcL4pbcYcr9qSfcfOMkEIvJYiBIxLr4=
24-
github.com/opentracing-contrib/go-grpc/test v0.0.0-20260320052726-de6f1ccdd147/go.mod h1:gvr3V5Pls/X/wRxvoNuGdDxrHUuTqHHUA1dZJmlAOuo=
23+
github.com/opentracing-contrib/go-grpc/test v0.0.0-20260404024518-e5db98260807 h1:nOLrhRxnJis0cGL5Iya0l4r50z4syb7HHWfDs1yMS8M=
24+
github.com/opentracing-contrib/go-grpc/test v0.0.0-20260404024518-e5db98260807/go.mod h1:gvr3V5Pls/X/wRxvoNuGdDxrHUuTqHHUA1dZJmlAOuo=
2525
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
2626
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
2727
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=

log/logger.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,17 @@ type LoggerConfig struct {
7474
attrs attribute.Set
7575
}
7676

77+
type experimentalOption interface {
78+
Experimental()
79+
}
80+
7781
// NewLoggerConfig returns a new [LoggerConfig] with all the options applied.
7882
func NewLoggerConfig(options ...LoggerOption) LoggerConfig {
7983
var c LoggerConfig
8084
for _, opt := range options {
85+
if _, ok := opt.(experimentalOption); ok {
86+
continue
87+
}
8188
c = opt.applyLogger(c)
8289
}
8390
return c

log/logger_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,3 +196,15 @@ func BenchmarkNewLoggerConfig(b *testing.B) {
196196
})
197197
}
198198
}
199+
200+
type testExperimentalOption struct {
201+
log.LoggerOption
202+
}
203+
204+
func (testExperimentalOption) Experimental() {}
205+
206+
func TestExperimentalOptionSafe(t *testing.T) {
207+
var opt testExperimentalOption
208+
209+
assert.NotPanics(t, func() { _ = log.NewLoggerConfig(opt) })
210+
}

metric/asyncfloat64.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ type Float64ObservableCounterConfig struct {
5151
func NewFloat64ObservableCounterConfig(opts ...Float64ObservableCounterOption) Float64ObservableCounterConfig {
5252
var config Float64ObservableCounterConfig
5353
for _, o := range opts {
54+
if _, ok := o.(experimentalOption); ok {
55+
continue
56+
}
5457
config = o.applyFloat64ObservableCounter(config)
5558
}
5659
return config
@@ -111,6 +114,9 @@ func NewFloat64ObservableUpDownCounterConfig(
111114
) Float64ObservableUpDownCounterConfig {
112115
var config Float64ObservableUpDownCounterConfig
113116
for _, o := range opts {
117+
if _, ok := o.(experimentalOption); ok {
118+
continue
119+
}
114120
config = o.applyFloat64ObservableUpDownCounter(config)
115121
}
116122
return config
@@ -168,6 +174,9 @@ type Float64ObservableGaugeConfig struct {
168174
func NewFloat64ObservableGaugeConfig(opts ...Float64ObservableGaugeOption) Float64ObservableGaugeConfig {
169175
var config Float64ObservableGaugeConfig
170176
for _, o := range opts {
177+
if _, ok := o.(experimentalOption); ok {
178+
continue
179+
}
171180
config = o.applyFloat64ObservableGauge(config)
172181
}
173182
return config

metric/asyncint64.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ type Int64ObservableCounterConfig struct {
5050
func NewInt64ObservableCounterConfig(opts ...Int64ObservableCounterOption) Int64ObservableCounterConfig {
5151
var config Int64ObservableCounterConfig
5252
for _, o := range opts {
53+
if _, ok := o.(experimentalOption); ok {
54+
continue
55+
}
5356
config = o.applyInt64ObservableCounter(config)
5457
}
5558
return config
@@ -110,6 +113,9 @@ func NewInt64ObservableUpDownCounterConfig(
110113
) Int64ObservableUpDownCounterConfig {
111114
var config Int64ObservableUpDownCounterConfig
112115
for _, o := range opts {
116+
if _, ok := o.(experimentalOption); ok {
117+
continue
118+
}
113119
config = o.applyInt64ObservableUpDownCounter(config)
114120
}
115121
return config
@@ -167,6 +173,9 @@ type Int64ObservableGaugeConfig struct {
167173
func NewInt64ObservableGaugeConfig(opts ...Int64ObservableGaugeOption) Int64ObservableGaugeConfig {
168174
var config Int64ObservableGaugeConfig
169175
for _, o := range opts {
176+
if _, ok := o.(experimentalOption); ok {
177+
continue
178+
}
170179
config = o.applyInt64ObservableGauge(config)
171180
}
172181
return config

metric/config.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,18 @@ type MeterOption interface {
4242
applyMeter(MeterConfig) MeterConfig
4343
}
4444

45+
type experimentalOption interface {
46+
Experimental()
47+
}
48+
4549
// NewMeterConfig creates a new MeterConfig and applies
4650
// all the given options.
4751
func NewMeterConfig(opts ...MeterOption) MeterConfig {
4852
var config MeterConfig
4953
for _, o := range opts {
54+
if _, ok := o.(experimentalOption); ok {
55+
continue
56+
}
5057
config = o.applyMeter(config)
5158
}
5259
return config

metric/config_test.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,3 +197,49 @@ func BenchmarkNewMeterConfig(b *testing.B) {
197197
})
198198
}
199199
}
200+
201+
type testExperimentalOption struct {
202+
metric.MeterOption
203+
metric.Int64CounterOption
204+
metric.Int64UpDownCounterOption
205+
metric.Int64HistogramOption
206+
metric.Int64GaugeOption
207+
metric.Float64CounterOption
208+
metric.Float64UpDownCounterOption
209+
metric.Float64HistogramOption
210+
metric.Float64GaugeOption
211+
metric.Int64ObservableCounterOption
212+
metric.Int64ObservableUpDownCounterOption
213+
metric.Int64ObservableGaugeOption
214+
metric.Float64ObservableCounterOption
215+
metric.Float64ObservableUpDownCounterOption
216+
metric.Float64ObservableGaugeOption
217+
metric.AddOption
218+
metric.RecordOption
219+
metric.ObserveOption
220+
}
221+
222+
func (testExperimentalOption) Experimental() {}
223+
224+
func TestExperimentalOptionSafe(t *testing.T) {
225+
var opt testExperimentalOption
226+
227+
assert.NotPanics(t, func() { _ = metric.NewMeterConfig(opt) })
228+
assert.NotPanics(t, func() { _ = metric.NewInt64CounterConfig(opt) })
229+
assert.NotPanics(t, func() { _ = metric.NewInt64UpDownCounterConfig(opt) })
230+
assert.NotPanics(t, func() { _ = metric.NewInt64HistogramConfig(opt) })
231+
assert.NotPanics(t, func() { _ = metric.NewInt64GaugeConfig(opt) })
232+
assert.NotPanics(t, func() { _ = metric.NewFloat64CounterConfig(opt) })
233+
assert.NotPanics(t, func() { _ = metric.NewFloat64UpDownCounterConfig(opt) })
234+
assert.NotPanics(t, func() { _ = metric.NewFloat64HistogramConfig(opt) })
235+
assert.NotPanics(t, func() { _ = metric.NewFloat64GaugeConfig(opt) })
236+
assert.NotPanics(t, func() { _ = metric.NewInt64ObservableCounterConfig(opt) })
237+
assert.NotPanics(t, func() { _ = metric.NewInt64ObservableUpDownCounterConfig(opt) })
238+
assert.NotPanics(t, func() { _ = metric.NewInt64ObservableGaugeConfig(opt) })
239+
assert.NotPanics(t, func() { _ = metric.NewFloat64ObservableCounterConfig(opt) })
240+
assert.NotPanics(t, func() { _ = metric.NewFloat64ObservableUpDownCounterConfig(opt) })
241+
assert.NotPanics(t, func() { _ = metric.NewFloat64ObservableGaugeConfig(opt) })
242+
assert.NotPanics(t, func() { _ = metric.NewAddConfig([]metric.AddOption{opt}) })
243+
assert.NotPanics(t, func() { _ = metric.NewRecordConfig([]metric.RecordOption{opt}) })
244+
assert.NotPanics(t, func() { _ = metric.NewObserveConfig([]metric.ObserveOption{opt}) })
245+
}

metric/instrument.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33

44
package metric // import "go.opentelemetry.io/otel/metric"
55

6-
import "go.opentelemetry.io/otel/attribute"
6+
import (
7+
"go.opentelemetry.io/otel/attribute"
8+
)
79

810
// Observable is used as a grouping mechanism for all instruments that are
911
// updated within a Callback.
@@ -228,6 +230,9 @@ type AddConfig struct {
228230
func NewAddConfig(opts []AddOption) AddConfig {
229231
config := AddConfig{attrs: *attribute.EmptySet()}
230232
for _, o := range opts {
233+
if _, ok := o.(experimentalOption); ok {
234+
continue
235+
}
231236
config = o.applyAdd(config)
232237
}
233238
return config
@@ -253,6 +258,9 @@ type RecordConfig struct {
253258
func NewRecordConfig(opts []RecordOption) RecordConfig {
254259
config := RecordConfig{attrs: *attribute.EmptySet()}
255260
for _, o := range opts {
261+
if _, ok := o.(experimentalOption); ok {
262+
continue
263+
}
256264
config = o.applyRecord(config)
257265
}
258266
return config
@@ -278,6 +286,9 @@ type ObserveConfig struct {
278286
func NewObserveConfig(opts []ObserveOption) ObserveConfig {
279287
config := ObserveConfig{attrs: *attribute.EmptySet()}
280288
for _, o := range opts {
289+
if _, ok := o.(experimentalOption); ok {
290+
continue
291+
}
281292
config = o.applyObserve(config)
282293
}
283294
return config

0 commit comments

Comments
 (0)