From 2b157d16d91b1c1ce5a67b62a1eae27cb0cfad9c Mon Sep 17 00:00:00 2001 From: wenjun Date: Tue, 30 Sep 2025 16:18:49 +0800 Subject: [PATCH 1/2] chore: sdk/metric/internal/x - generate x package from x component template (#7386) --- sdk/metric/internal/gen.go | 8 ++++ sdk/metric/internal/x/enabled_instrument.go | 12 +++++ .../internal/x/enabled_instrument_test.go | 23 ++++++++++ sdk/metric/internal/x/x.go | 45 ++++++++----------- sdk/metric/internal/x/x_test.go | 34 +++++++++++--- 5 files changed, 91 insertions(+), 31 deletions(-) create mode 100644 sdk/metric/internal/gen.go create mode 100644 sdk/metric/internal/x/enabled_instrument.go create mode 100644 sdk/metric/internal/x/enabled_instrument_test.go diff --git a/sdk/metric/internal/gen.go b/sdk/metric/internal/gen.go new file mode 100644 index 00000000000..7dae2ebe7dd --- /dev/null +++ b/sdk/metric/internal/gen.go @@ -0,0 +1,8 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// Package internal provides internal functionality for the sdk/metric package. +package internal // import "go.opentelemetry.io/otel/sdk/metric/internal" + +//go:generate gotmpl --body=../../../internal/shared/x/x.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/otel/sdk/metric\" }" --out=x/x.go +//go:generate gotmpl --body=../../../internal/shared/x/x_test.go.tmpl "--data={}" --out=x/x_test.go diff --git a/sdk/metric/internal/x/enabled_instrument.go b/sdk/metric/internal/x/enabled_instrument.go new file mode 100644 index 00000000000..27601582f35 --- /dev/null +++ b/sdk/metric/internal/x/enabled_instrument.go @@ -0,0 +1,12 @@ +package x + +import "context" + +// EnabledInstrument interface is implemented by synchronous instruments. +type EnabledInstrument interface { + // Enabled reports whether the instrument will process measurements for the given context. + // + // This function can be used in places where measuring an instrument + // would result in computationally expensive operations. + Enabled(context.Context) bool +} diff --git a/sdk/metric/internal/x/enabled_instrument_test.go b/sdk/metric/internal/x/enabled_instrument_test.go new file mode 100644 index 00000000000..4ea7fa19a33 --- /dev/null +++ b/sdk/metric/internal/x/enabled_instrument_test.go @@ -0,0 +1,23 @@ +package x + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" +) + +type testInstrument struct{} + +func (t *testInstrument) Enabled(ctx context.Context) bool { + return true +} + +func TestEnabledInstrument(t *testing.T) { + var ei EnabledInstrument = &testInstrument{} + + ctx := context.Background() + enabled := ei.Enabled(ctx) + + require.True(t, enabled, "Enabled() should return true") +} diff --git a/sdk/metric/internal/x/x.go b/sdk/metric/internal/x/x.go index 294dcf8469e..87aea94a47d 100644 --- a/sdk/metric/internal/x/x.go +++ b/sdk/metric/internal/x/x.go @@ -1,36 +1,38 @@ +// Code generated by gotmpl. DO NOT MODIFY. +// source: internal/shared/x/x.go.tmpl + // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// Package x contains support for OTel metric SDK experimental features. -// -// This package should only be used for features defined in the specification. -// It should not be used for experiments or new project ideas. +// Package x documents experimental features for [go.opentelemetry.io/otel/sdk/metric]. package x // import "go.opentelemetry.io/otel/sdk/metric/internal/x" import ( - "context" "os" ) // 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 + keys []string parse func(v string) (T, bool) } -//nolint:unused -func newFeature[T any](suffix string, parse func(string) (T, bool)) Feature[T] { +func newFeature[T any](suffix []string, parse func(string) (T, bool)) Feature[T] { const envKeyRoot = "OTEL_GO_X_" + keys := make([]string, 0, len(suffix)) + for _, s := range suffix { + keys = append(keys, envKeyRoot+s) + } return Feature[T]{ - key: envKeyRoot + suffix, + keys: keys, parse: parse, } } -// Key returns the environment variable key that needs to be set to enable the +// Keys returns the environment variable keys that can be set to enable the // feature. -func (f Feature[T]) Key() string { return f.key } +func (f Feature[T]) Keys() []string { return f.keys } // 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 @@ -40,11 +42,13 @@ func (f Feature[T]) Lookup() (v T, ok bool) { // // > 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 + for _, key := range f.keys { + vRaw := os.Getenv(key) + if vRaw != "" { + return f.parse(vRaw) + } } - return f.parse(vRaw) + return v, ok } // Enabled reports whether the feature is enabled. @@ -52,14 +56,3 @@ func (f Feature[T]) Enabled() bool { _, ok := f.Lookup() return ok } - -// EnabledInstrument informs whether the instrument is enabled. -// -// EnabledInstrument interface is implemented by synchronous instruments. -type EnabledInstrument interface { - // Enabled reports whether the instrument will process measurements for the given context. - // - // This function can be used in places where measuring an instrument - // would result in computationally expensive operations. - Enabled(context.Context) bool -} diff --git a/sdk/metric/internal/x/x_test.go b/sdk/metric/internal/x/x_test.go index d7d5e41ce4a..a715d7608a7 100644 --- a/sdk/metric/internal/x/x_test.go +++ b/sdk/metric/internal/x/x_test.go @@ -1,15 +1,42 @@ +// Code generated by gotmpl. DO NOT MODIFY. +// source: internal/shared/x/x_text.go.tmpl + // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 package x import ( + "strings" "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +const ( + mockKey = "OTEL_GO_X_MOCK_FEATURE" + mockKey2 = "OTEL_GO_X_MOCK_FEATURE2" ) -//nolint:unused +var mockFeature = newFeature([]string{"MOCK_FEATURE", "MOCK_FEATURE2"}, func(v string) (string, bool) { + if strings.EqualFold(v, "true") { + return v, true + } + return "", false +}) + +func TestFeature(t *testing.T) { + require.Contains(t, mockFeature.Keys(), mockKey) + require.Contains(t, mockFeature.Keys(), mockKey2) + + t.Run("100", run(setenv(mockKey, "100"), assertDisabled(mockFeature))) + t.Run("true", run(setenv(mockKey, "true"), assertEnabled(mockFeature, "true"))) + t.Run("True", run(setenv(mockKey, "True"), assertEnabled(mockFeature, "True"))) + t.Run("false", run(setenv(mockKey, "false"), assertDisabled(mockFeature))) + t.Run("empty", run(assertDisabled(mockFeature))) +} + func run(steps ...func(*testing.T)) func(*testing.T) { return func(t *testing.T) { t.Helper() @@ -19,12 +46,10 @@ func run(steps ...func(*testing.T)) func(*testing.T) { } } -//nolint:unused -func setenv(k, v string) func(t *testing.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) } } -//nolint:unused func assertEnabled[T any](f Feature[T], want T) func(*testing.T) { return func(t *testing.T) { t.Helper() @@ -36,7 +61,6 @@ func assertEnabled[T any](f Feature[T], want T) func(*testing.T) { } } -//nolint:unused func assertDisabled[T any](f Feature[T]) func(*testing.T) { var zero T return func(t *testing.T) { From 071f8c8797bbcb7cfd94bf8cac37eef38d58a647 Mon Sep 17 00:00:00 2001 From: wenjun Date: Tue, 14 Oct 2025 17:12:40 +0800 Subject: [PATCH 2/2] chore: update generated metric instrumentation file (#7386) --- sdk/metric/internal/x/enabled_instrument.go | 5 ++++- sdk/metric/internal/x/enabled_instrument_test.go | 7 +++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/sdk/metric/internal/x/enabled_instrument.go b/sdk/metric/internal/x/enabled_instrument.go index 27601582f35..9558ae5e8f9 100644 --- a/sdk/metric/internal/x/enabled_instrument.go +++ b/sdk/metric/internal/x/enabled_instrument.go @@ -1,4 +1,7 @@ -package x +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package x // import "go.opentelemetry.io/otel/sdk/metric/internal/x" import "context" diff --git a/sdk/metric/internal/x/enabled_instrument_test.go b/sdk/metric/internal/x/enabled_instrument_test.go index 4ea7fa19a33..097d24e7fe3 100644 --- a/sdk/metric/internal/x/enabled_instrument_test.go +++ b/sdk/metric/internal/x/enabled_instrument_test.go @@ -1,3 +1,6 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + package x import ( @@ -9,14 +12,14 @@ import ( type testInstrument struct{} -func (t *testInstrument) Enabled(ctx context.Context) bool { +func (*testInstrument) Enabled(_ context.Context) bool { return true } func TestEnabledInstrument(t *testing.T) { var ei EnabledInstrument = &testInstrument{} - ctx := context.Background() + ctx := t.Context() enabled := ei.Enabled(ctx) require.True(t, enabled, "Enabled() should return true")