You've already forked opentelemetry-go
mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-11-25 22:41:46 +02:00
Rename Self-Observability as just Observability (#7302)
Self-Observability is a redundant term, the self being instrumented is always the self that observability is being provided for. Remove this redundancy. Continue to provide backwards compatibility for any users already using `OTEL_GO_X_SELF_OBSERVABILITY` to enable the feature. --------- Co-authored-by: Damien Mathieu <42@dmathieu.com>
This commit is contained in:
@@ -23,6 +23,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
||||
|
||||
### Changed
|
||||
|
||||
- Rename the `OTEL_GO_X_SELF_OBSERVABILITY` environment variable to `OTEL_GO_X_OBSERVABILITY` in `go.opentelemetry.io/otel/sdk/trace`, `go.opentelemetry.io/otel/sdk/log`, and `go.opentelemetry.io/otel/exporters/stdout/stdouttrace`. (#7302)
|
||||
- Improve performance of histogram `Record` in `go.opentelemetry.io/otel/sdk/metric` when min and max are disabled using `NoMinMax`. (#7306)
|
||||
|
||||
<!-- Released section -->
|
||||
|
||||
@@ -684,8 +684,8 @@ This section outlines the best practices for building instrumentation in OpenTel
|
||||
|
||||
#### Environment Variable Activation
|
||||
|
||||
Self-observability features are currently experimental.
|
||||
They should be disabled by default and activated through the `OTEL_GO_X_SELF_OBSERVABILITY` environment variable.
|
||||
Observability features are currently experimental.
|
||||
They should be disabled by default and activated through the `OTEL_GO_X_OBSERVABILITY` environment variable.
|
||||
This follows the established experimental feature pattern used throughout the SDK.
|
||||
|
||||
Components should check for this environment variable using a consistent pattern:
|
||||
@@ -693,8 +693,8 @@ Components should check for this environment variable using a consistent pattern
|
||||
```go
|
||||
import "go.opentelemetry.io/otel/*/internal/x"
|
||||
|
||||
if x.SelfObservability.Enabled() {
|
||||
// Initialize self-observability metrics
|
||||
if x.Observability.Enabled() {
|
||||
// Initialize observability metrics
|
||||
}
|
||||
```
|
||||
|
||||
@@ -769,7 +769,7 @@ type instrumentation struct {
|
||||
}
|
||||
|
||||
func newInstrumentation() (*instrumentation, error) {
|
||||
if !x.SelfObservability.Enabled() {
|
||||
if !x.Observability.Enabled() {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -796,7 +796,7 @@ func newInstrumentation() (*instrumentation, error) {
|
||||
// ❌ Avoid this pattern.
|
||||
func (c *Component) initObservability() {
|
||||
// Initialize observability metrics
|
||||
if !x.SelfObservability.Enabled() {
|
||||
if !x.Observability.Enabled() {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -932,17 +932,17 @@ Demonstrate the impact (allocs/op, B/op, ns/op) in enabled/disabled scenarios:
|
||||
func BenchmarkExportSpans(b *testing.B) {
|
||||
scenarios := []struct {
|
||||
name string
|
||||
selfObsEnabled bool
|
||||
obsEnabled bool
|
||||
}{
|
||||
{"SelfObsDisabled", false},
|
||||
{"SelfObsEnabled", true},
|
||||
{"ObsDisabled", false},
|
||||
{"ObsEnabled", true},
|
||||
}
|
||||
|
||||
for _, scenario := range scenarios {
|
||||
b.Run(scenario.name, func(b *testing.B) {
|
||||
b.Setenv(
|
||||
"OTEL_GO_X_SELF_OBSERVABILITY",
|
||||
strconv.FormatBool(scenario.selfObsEnabled),
|
||||
"OTEL_GO_X_OBSERVABILITY",
|
||||
strconv.FormatBool(scenario.obsEnabled),
|
||||
)
|
||||
|
||||
exporter := NewExporter()
|
||||
@@ -965,7 +965,7 @@ Errors should be reported back to the caller if possible, and partial failures s
|
||||
|
||||
```go
|
||||
func newInstrumentation() (*instrumentation, error) {
|
||||
if !x.SelfObservability.Enabled() {
|
||||
if !x.Observability.Enabled() {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -981,7 +981,7 @@ func newInstrumentation() (*instrumentation, error) {
|
||||
```go
|
||||
// ❌ Avoid this pattern.
|
||||
func newInstrumentation() *instrumentation {
|
||||
if !x.SelfObservability.Enabled() {
|
||||
if !x.Observability.Enabled() {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -1038,7 +1038,7 @@ func (e *Exporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan)
|
||||
|
||||
#### Semantic Conventions Compliance
|
||||
|
||||
All self-observability metrics should follow the [OpenTelemetry Semantic Conventions for SDK metrics](https://github.com/open-telemetry/semantic-conventions/blob/1cf2476ae5e518225a766990a28a6d5602bd5a30/docs/otel/sdk-metrics.md).
|
||||
All observability metrics should follow the [OpenTelemetry Semantic Conventions for SDK metrics](https://github.com/open-telemetry/semantic-conventions/blob/1cf2476ae5e518225a766990a28a6d5602bd5a30/docs/otel/sdk-metrics.md).
|
||||
|
||||
Use the metric semantic conventions convenience package [otelconv](./semconv/v1.37.0/otelconv/metric.go).
|
||||
|
||||
@@ -1087,7 +1087,7 @@ See [stdouttrace exporter example](./exporters/stdout/stdouttrace/internal/gen.g
|
||||
Use deterministic testing with isolated state:
|
||||
|
||||
```go
|
||||
func TestSelfObservability(t *testing.T) {
|
||||
func TestObservability(t *testing.T) {
|
||||
// Restore state after test to ensure this does not affect other tests.
|
||||
prev := otel.GetMeterProvider()
|
||||
t.Cleanup(func() { otel.SetMeterProvider(prev) })
|
||||
@@ -1098,7 +1098,7 @@ func TestSelfObservability(t *testing.T) {
|
||||
otel.SetMeterProvider(meterProvider)
|
||||
|
||||
// Use t.Setenv to ensure environment variable is restored after test.
|
||||
t.Setenv("OTEL_GO_X_SELF_OBSERVABILITY", "true")
|
||||
t.Setenv("OTEL_GO_X_OBSERVABILITY", "true")
|
||||
|
||||
// Reset component ID counter to ensure deterministic component names.
|
||||
componentIDCounter.Store(0)
|
||||
|
||||
@@ -98,7 +98,7 @@ type Instrumentation struct {
|
||||
//
|
||||
// If the experimental observability is disabled, nil is returned.
|
||||
func NewInstrumentation(id int64) (*Instrumentation, error) {
|
||||
if !x.SelfObservability.Enabled() {
|
||||
if !x.Observability.Enabled() {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ func TestNewInstrumentationObservabiltyErrors(t *testing.T) {
|
||||
mp := &errMeterProvider{err: assert.AnError}
|
||||
otel.SetMeterProvider(mp)
|
||||
|
||||
t.Setenv("OTEL_GO_X_SELF_OBSERVABILITY", "true")
|
||||
t.Setenv("OTEL_GO_X_OBSERVABILITY", "true")
|
||||
|
||||
_, err := observ.NewInstrumentation(ID)
|
||||
require.ErrorIs(t, err, assert.AnError, "new instrument errors")
|
||||
@@ -76,7 +76,7 @@ func TestNewInstrumentationObservabiltyErrors(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNewInstrumentationObservabiltyDisabled(t *testing.T) {
|
||||
// Do not set OTEL_GO_X_SELF_OBSERVABILITY.
|
||||
// Do not set OTEL_GO_X_OBSERVABILITY.
|
||||
got, err := observ.NewInstrumentation(ID)
|
||||
assert.NoError(t, err)
|
||||
assert.Nil(t, got)
|
||||
@@ -85,7 +85,7 @@ func TestNewInstrumentationObservabiltyDisabled(t *testing.T) {
|
||||
func setup(t *testing.T) (*observ.Instrumentation, func() metricdata.ScopeMetrics) {
|
||||
t.Helper()
|
||||
|
||||
t.Setenv("OTEL_GO_X_SELF_OBSERVABILITY", "true")
|
||||
t.Setenv("OTEL_GO_X_OBSERVABILITY", "true")
|
||||
|
||||
original := otel.GetMeterProvider()
|
||||
t.Cleanup(func() { otel.SetMeterProvider(original) })
|
||||
@@ -220,7 +220,7 @@ func TestInstrumentationExportSpansPartialErrored(t *testing.T) {
|
||||
}
|
||||
|
||||
func BenchmarkInstrumentationExportSpans(b *testing.B) {
|
||||
b.Setenv("OTEL_GO_X_SELF_OBSERVABILITY", "true")
|
||||
b.Setenv("OTEL_GO_X_OBSERVABILITY", "true")
|
||||
inst, err := observ.NewInstrumentation(ID)
|
||||
if err != nil {
|
||||
b.Fatalf("failed to create instrumentation: %v", err)
|
||||
|
||||
@@ -8,13 +8,13 @@ See the [Compatibility and Stability](#compatibility-and-stability) section for
|
||||
|
||||
## Features
|
||||
|
||||
- [Self-Observability](#self-observability)
|
||||
- [Observability](#observability)
|
||||
|
||||
### Self-Observability
|
||||
### Observability
|
||||
|
||||
The `stdouttrace` exporter provides a self-observability feature that allows you to monitor the SDK itself.
|
||||
The `stdouttrace` exporter can be configured to provide observability about itself using OpenTelemetry metrics.
|
||||
|
||||
To opt-in, set the environment variable `OTEL_GO_X_SELF_OBSERVABILITY` to `true`.
|
||||
To opt-in, set the environment variable `OTEL_GO_X_OBSERVABILITY` to `true`.
|
||||
|
||||
When enabled, the SDK will create the following metrics using the global `MeterProvider`:
|
||||
|
||||
|
||||
@@ -9,37 +9,44 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// SelfObservability is an experimental feature flag that determines if SDK
|
||||
// self-observability metrics are enabled.
|
||||
// Observability is an experimental feature flag that determines if exporter
|
||||
// observability metrics are enabled.
|
||||
//
|
||||
// To enable this feature set the OTEL_GO_X_SELF_OBSERVABILITY environment variable
|
||||
// To enable this feature set the OTEL_GO_X_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.EqualFold(v, "true") {
|
||||
return v, true
|
||||
}
|
||||
return "", false
|
||||
})
|
||||
var Observability = newFeature(
|
||||
[]string{"OBSERVABILITY", "SELF_OBSERVABILITY"},
|
||||
func(v string) (string, bool) {
|
||||
if strings.EqualFold(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
|
||||
keys []string
|
||||
parse func(v string) (T, bool)
|
||||
}
|
||||
|
||||
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
|
||||
@@ -49,11 +56,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.
|
||||
|
||||
@@ -10,15 +10,18 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestSelfObservability(t *testing.T) {
|
||||
const key = "OTEL_GO_X_SELF_OBSERVABILITY"
|
||||
require.Equal(t, key, SelfObservability.Key())
|
||||
func TestObservability(t *testing.T) {
|
||||
const key = "OTEL_GO_X_OBSERVABILITY"
|
||||
require.Contains(t, Observability.Keys(), 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)))
|
||||
const altKey = "OTEL_GO_X_SELF_OBSERVABILITY"
|
||||
require.Contains(t, Observability.Keys(), altKey)
|
||||
|
||||
t.Run("100", run(setenv(key, "100"), assertDisabled(Observability)))
|
||||
t.Run("true", run(setenv(key, "true"), assertEnabled(Observability, "true")))
|
||||
t.Run("True", run(setenv(key, "True"), assertEnabled(Observability, "True")))
|
||||
t.Run("false", run(setenv(key, "false"), assertDisabled(Observability)))
|
||||
t.Run("empty", run(assertDisabled(Observability)))
|
||||
}
|
||||
|
||||
func run(steps ...func(*testing.T)) func(*testing.T) {
|
||||
|
||||
@@ -239,7 +239,7 @@ func TestExporterShutdownNoError(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSelfObservability(t *testing.T) {
|
||||
func TestObservability(t *testing.T) {
|
||||
defaultCallExportSpans := func(t *testing.T, exporter *stdouttrace.Exporter) {
|
||||
require.NoError(t, exporter.ExportSpans(context.Background(), tracetest.SpanStubs{
|
||||
{Name: "/foo"},
|
||||
@@ -338,7 +338,7 @@ func TestSelfObservability(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.enabled {
|
||||
t.Setenv("OTEL_GO_X_SELF_OBSERVABILITY", "true")
|
||||
t.Setenv("OTEL_GO_X_OBSERVABILITY", "true")
|
||||
|
||||
// Reset component name counter for each test.
|
||||
_ = counter.SetExporterID(0)
|
||||
@@ -389,8 +389,8 @@ func BenchmarkExporterExportSpans(b *testing.B) {
|
||||
_ = err
|
||||
}
|
||||
|
||||
b.Run("SelfObservability", func(b *testing.B) {
|
||||
b.Setenv("OTEL_GO_X_SELF_OBSERVABILITY", "true")
|
||||
b.Run("Observability", func(b *testing.B) {
|
||||
b.Setenv("OTEL_GO_X_OBSERVABILITY", "true")
|
||||
run(b)
|
||||
})
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
// newRecordCounterIncr returns a function that increments the log record
|
||||
// counter metric. If observability is disabled, it returns nil.
|
||||
func newRecordCounterIncr() (func(context.Context), error) {
|
||||
if !x.SelfObservability.Enabled() {
|
||||
if !x.Observability.Enabled() {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -8,13 +8,13 @@ See the [Compatibility and Stability](#compatibility-and-stability) section for
|
||||
|
||||
## Features
|
||||
|
||||
- [Self-Observability](#self-observability)
|
||||
- [Observability](#observability)
|
||||
|
||||
### Self-Observability
|
||||
### Observability
|
||||
|
||||
The Logs SDK provides a self-observability feature that allows you to monitor the SDK itself.
|
||||
The Logs SDK can be configured to provide observability about itself using OpenTelemetry metrics.
|
||||
|
||||
To opt-in, set the environment variable `OTEL_GO_X_SELF_OBSERVABILITY` to `true`.
|
||||
To opt-in, set the environment variable `OTEL_GO_X_OBSERVABILITY` to `true`.
|
||||
|
||||
When enabled, the SDK will create the following metrics using the global `MeterProvider`:
|
||||
|
||||
|
||||
@@ -9,37 +9,44 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// SelfObservability is an experimental feature flag that determines if SDK
|
||||
// self-observability metrics are enabled.
|
||||
// Observability is an experimental feature flag that determines if SDK
|
||||
// observability metrics are enabled.
|
||||
//
|
||||
// To enable this feature set the OTEL_GO_X_SELF_OBSERVABILITY environment variable
|
||||
// To enable this feature set the OTEL_GO_X_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.EqualFold(v, "true") {
|
||||
return v, true
|
||||
}
|
||||
return "", false
|
||||
})
|
||||
var Observability = newFeature(
|
||||
[]string{"OBSERVABILITY", "SELF_OBSERVABILITY"},
|
||||
func(v string) (string, bool) {
|
||||
if strings.EqualFold(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
|
||||
keys []string
|
||||
parse func(v string) (T, bool)
|
||||
}
|
||||
|
||||
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
|
||||
@@ -49,11 +56,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.
|
||||
|
||||
@@ -10,15 +10,18 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestSelfObservability(t *testing.T) {
|
||||
const key = "OTEL_GO_X_SELF_OBSERVABILITY"
|
||||
require.Equal(t, key, SelfObservability.Key())
|
||||
func TestObservability(t *testing.T) {
|
||||
const key = "OTEL_GO_X_OBSERVABILITY"
|
||||
require.Contains(t, Observability.Keys(), 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)))
|
||||
const altKey = "OTEL_GO_X_SELF_OBSERVABILITY"
|
||||
require.Contains(t, Observability.Keys(), altKey)
|
||||
|
||||
t.Run("100", run(setenv(key, "100"), assertDisabled(Observability)))
|
||||
t.Run("true", run(setenv(key, "true"), assertEnabled(Observability, "true")))
|
||||
t.Run("True", run(setenv(key, "True"), assertEnabled(Observability, "True")))
|
||||
t.Run("false", run(setenv(key, "false"), assertDisabled(Observability)))
|
||||
t.Run("empty", run(assertDisabled(Observability)))
|
||||
}
|
||||
|
||||
func run(steps ...func(*testing.T)) func(*testing.T) {
|
||||
|
||||
@@ -93,7 +93,7 @@ func BenchmarkLoggerEmitObservability(b *testing.B) {
|
||||
b.Run("Disabled", run(newLogger(lp, scope)))
|
||||
|
||||
b.Run("Enabled", func(b *testing.B) {
|
||||
b.Setenv("OTEL_GO_X_SELF_OBSERVABILITY", "true")
|
||||
b.Setenv("OTEL_GO_X_OBSERVABILITY", "true")
|
||||
|
||||
run(newLogger(lp, scope))(b)
|
||||
})
|
||||
|
||||
@@ -402,30 +402,30 @@ func TestLoggerEnabled(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoggerSelfObservability(t *testing.T) {
|
||||
func TestLoggerObservability(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
selfObservabilityEnabled bool
|
||||
records []log.Record
|
||||
wantLogRecordCount int64
|
||||
name string
|
||||
enabled bool
|
||||
records []log.Record
|
||||
wantLogRecordCount int64
|
||||
}{
|
||||
{
|
||||
name: "Disabled",
|
||||
selfObservabilityEnabled: false,
|
||||
records: []log.Record{{}, {}},
|
||||
wantLogRecordCount: 0,
|
||||
name: "Disabled",
|
||||
enabled: false,
|
||||
records: []log.Record{{}, {}},
|
||||
wantLogRecordCount: 0,
|
||||
},
|
||||
{
|
||||
name: "Enabled",
|
||||
selfObservabilityEnabled: true,
|
||||
records: []log.Record{{}, {}, {}, {}, {}},
|
||||
wantLogRecordCount: 5,
|
||||
name: "Enabled",
|
||||
enabled: true,
|
||||
records: []log.Record{{}, {}, {}, {}, {}},
|
||||
wantLogRecordCount: 5,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Setenv("OTEL_GO_X_SELF_OBSERVABILITY", strconv.FormatBool(tc.selfObservabilityEnabled))
|
||||
t.Setenv("OTEL_GO_X_OBSERVABILITY", strconv.FormatBool(tc.enabled))
|
||||
prev := otel.GetMeterProvider()
|
||||
t.Cleanup(func() {
|
||||
otel.SetMeterProvider(prev)
|
||||
@@ -469,7 +469,7 @@ func TestLoggerSelfObservability(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewLoggerSelfObservabilityErrorHandled(t *testing.T) {
|
||||
func TestNewLoggerObservabilityErrorHandled(t *testing.T) {
|
||||
errHandler := otel.GetErrorHandler()
|
||||
t.Cleanup(func() {
|
||||
otel.SetErrorHandler(errHandler)
|
||||
@@ -483,7 +483,7 @@ func TestNewLoggerSelfObservabilityErrorHandled(t *testing.T) {
|
||||
t.Cleanup(func() { otel.SetMeterProvider(orig) })
|
||||
otel.SetMeterProvider(&errMeterProvider{err: assert.AnError})
|
||||
|
||||
t.Setenv("OTEL_GO_X_SELF_OBSERVABILITY", "true")
|
||||
t.Setenv("OTEL_GO_X_OBSERVABILITY", "true")
|
||||
l := newLogger(NewLoggerProvider(), instrumentation.Scope{})
|
||||
_ = l
|
||||
require.Len(t, errs, 1)
|
||||
|
||||
@@ -78,10 +78,10 @@ type batchSpanProcessor struct {
|
||||
queue chan ReadOnlySpan
|
||||
dropped uint32
|
||||
|
||||
selfObservabilityEnabled bool
|
||||
callbackRegistration metric.Registration
|
||||
spansProcessedCounter otelconv.SDKProcessorSpanProcessed
|
||||
componentNameAttr attribute.KeyValue
|
||||
observabilityEnabled bool
|
||||
callbackRegistration metric.Registration
|
||||
spansProcessedCounter otelconv.SDKProcessorSpanProcessed
|
||||
componentNameAttr attribute.KeyValue
|
||||
|
||||
batch []ReadOnlySpan
|
||||
batchMutex sync.Mutex
|
||||
@@ -124,8 +124,8 @@ func NewBatchSpanProcessor(exporter SpanExporter, options ...BatchSpanProcessorO
|
||||
stopCh: make(chan struct{}),
|
||||
}
|
||||
|
||||
if x.SelfObservability.Enabled() {
|
||||
bsp.selfObservabilityEnabled = true
|
||||
if x.Observability.Enabled() {
|
||||
bsp.observabilityEnabled = true
|
||||
bsp.componentNameAttr = componentName()
|
||||
|
||||
var err error
|
||||
@@ -172,7 +172,7 @@ func newBSPObs(
|
||||
qMax int64,
|
||||
) (otelconv.SDKProcessorSpanProcessed, metric.Registration, error) {
|
||||
meter := otel.GetMeterProvider().Meter(
|
||||
selfObsScopeName,
|
||||
obsScopeName,
|
||||
metric.WithInstrumentationVersion(sdk.Version()),
|
||||
metric.WithSchemaURL(semconv.SchemaURL),
|
||||
)
|
||||
@@ -242,7 +242,7 @@ func (bsp *batchSpanProcessor) Shutdown(ctx context.Context) error {
|
||||
case <-ctx.Done():
|
||||
err = ctx.Err()
|
||||
}
|
||||
if bsp.selfObservabilityEnabled {
|
||||
if bsp.observabilityEnabled {
|
||||
err = errors.Join(err, bsp.callbackRegistration.Unregister())
|
||||
}
|
||||
})
|
||||
@@ -357,7 +357,7 @@ func (bsp *batchSpanProcessor) exportSpans(ctx context.Context) error {
|
||||
|
||||
if l := len(bsp.batch); l > 0 {
|
||||
global.Debug("exporting spans", "count", len(bsp.batch), "total_dropped", atomic.LoadUint32(&bsp.dropped))
|
||||
if bsp.selfObservabilityEnabled {
|
||||
if bsp.observabilityEnabled {
|
||||
bsp.spansProcessedCounter.Add(ctx, int64(l),
|
||||
bsp.componentNameAttr,
|
||||
bsp.spansProcessedCounter.AttrComponentType(otelconv.ComponentTypeBatchingSpanProcessor))
|
||||
@@ -470,7 +470,7 @@ func (bsp *batchSpanProcessor) enqueueBlockOnQueueFull(ctx context.Context, sd R
|
||||
case bsp.queue <- sd:
|
||||
return true
|
||||
case <-ctx.Done():
|
||||
if bsp.selfObservabilityEnabled {
|
||||
if bsp.observabilityEnabled {
|
||||
bsp.spansProcessedCounter.Add(ctx, 1,
|
||||
bsp.componentNameAttr,
|
||||
bsp.spansProcessedCounter.AttrComponentType(otelconv.ComponentTypeBatchingSpanProcessor),
|
||||
@@ -490,7 +490,7 @@ func (bsp *batchSpanProcessor) enqueueDrop(ctx context.Context, sd ReadOnlySpan)
|
||||
return true
|
||||
default:
|
||||
atomic.AddUint32(&bsp.dropped, 1)
|
||||
if bsp.selfObservabilityEnabled {
|
||||
if bsp.observabilityEnabled {
|
||||
bsp.spansProcessedCounter.Add(ctx, 1,
|
||||
bsp.componentNameAttr,
|
||||
bsp.spansProcessedCounter.AttrComponentType(otelconv.ComponentTypeBatchingSpanProcessor),
|
||||
|
||||
@@ -654,7 +654,7 @@ var dropSpanMetricsView = sdkmetric.NewView(
|
||||
)
|
||||
|
||||
func TestBatchSpanProcessorMetricsDisabled(t *testing.T) {
|
||||
t.Setenv("OTEL_GO_X_SELF_OBSERVABILITY", "false")
|
||||
t.Setenv("OTEL_GO_X_OBSERVABILITY", "false")
|
||||
tp := basicTracerProvider(t)
|
||||
reader := sdkmetric.NewManualReader()
|
||||
meterProvider := sdkmetric.NewMeterProvider(
|
||||
@@ -693,7 +693,7 @@ func TestBatchSpanProcessorMetricsDisabled(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestBatchSpanProcessorMetrics(t *testing.T) {
|
||||
t.Setenv("OTEL_GO_X_SELF_OBSERVABILITY", "true")
|
||||
t.Setenv("OTEL_GO_X_OBSERVABILITY", "true")
|
||||
tp := basicTracerProvider(t)
|
||||
reader := sdkmetric.NewManualReader()
|
||||
meterProvider := sdkmetric.NewMeterProvider(
|
||||
@@ -719,16 +719,16 @@ func TestBatchSpanProcessorMetrics(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||
defer cancel()
|
||||
assert.NoError(t, me.waitForSpans(ctx, 2))
|
||||
assertSelfObsScopeMetrics(t, internalBsp.componentNameAttr, reader,
|
||||
assertObsScopeMetrics(t, internalBsp.componentNameAttr, reader,
|
||||
expectMetrics{queueCapacity: 2, queueSize: 0, successProcessed: 2})
|
||||
// Generate 3 spans. 2 fill the queue, and 1 is dropped because the queue is full.
|
||||
generateSpan(t, tr, testOption{genNumSpans: 3})
|
||||
assertSelfObsScopeMetrics(t, internalBsp.componentNameAttr, reader,
|
||||
assertObsScopeMetrics(t, internalBsp.componentNameAttr, reader,
|
||||
expectMetrics{queueCapacity: 2, queueSize: 2, queueFullProcessed: 1, successProcessed: 2})
|
||||
}
|
||||
|
||||
func TestBatchSpanProcessorBlockingMetrics(t *testing.T) {
|
||||
t.Setenv("OTEL_GO_X_SELF_OBSERVABILITY", "true")
|
||||
t.Setenv("OTEL_GO_X_OBSERVABILITY", "true")
|
||||
tp := basicTracerProvider(t)
|
||||
reader := sdkmetric.NewManualReader()
|
||||
meterProvider := sdkmetric.NewMeterProvider(
|
||||
@@ -756,7 +756,7 @@ func TestBatchSpanProcessorBlockingMetrics(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||
defer cancel()
|
||||
assert.NoError(t, me.waitForSpans(ctx, 2))
|
||||
assertSelfObsScopeMetrics(t, internalBsp.componentNameAttr, reader,
|
||||
assertObsScopeMetrics(t, internalBsp.componentNameAttr, reader,
|
||||
expectMetrics{queueCapacity: 2, queueSize: 0, successProcessed: 2})
|
||||
// Generate 2 spans to fill the queue.
|
||||
generateSpan(t, tr, testOption{genNumSpans: 2})
|
||||
@@ -764,14 +764,14 @@ func TestBatchSpanProcessorBlockingMetrics(t *testing.T) {
|
||||
// Generate a span which blocks because the queue is full.
|
||||
generateSpan(t, tr, testOption{genNumSpans: 1})
|
||||
}()
|
||||
assertSelfObsScopeMetrics(t, internalBsp.componentNameAttr, reader,
|
||||
assertObsScopeMetrics(t, internalBsp.componentNameAttr, reader,
|
||||
expectMetrics{queueCapacity: 2, queueSize: 2, successProcessed: 2})
|
||||
|
||||
// Use ForceFlush to force the span that is blocking on the full queue to be dropped.
|
||||
ctx, cancel = context.WithTimeout(context.Background(), 10*time.Millisecond)
|
||||
defer cancel()
|
||||
assert.Error(t, tp.ForceFlush(ctx))
|
||||
assertSelfObsScopeMetrics(t, internalBsp.componentNameAttr, reader,
|
||||
assertObsScopeMetrics(t, internalBsp.componentNameAttr, reader,
|
||||
expectMetrics{queueCapacity: 2, queueSize: 2, queueFullProcessed: 1, successProcessed: 2})
|
||||
}
|
||||
|
||||
@@ -782,7 +782,7 @@ type expectMetrics struct {
|
||||
queueFullProcessed int64
|
||||
}
|
||||
|
||||
func assertSelfObsScopeMetrics(t *testing.T, componentNameAttr attribute.KeyValue, reader sdkmetric.Reader,
|
||||
func assertObsScopeMetrics(t *testing.T, componentNameAttr attribute.KeyValue, reader sdkmetric.Reader,
|
||||
expectation expectMetrics,
|
||||
) {
|
||||
t.Helper()
|
||||
|
||||
@@ -8,13 +8,13 @@ See the [Compatibility and Stability](#compatibility-and-stability) section for
|
||||
|
||||
## Features
|
||||
|
||||
- [Self-Observability](#self-observability)
|
||||
- [Observability](#observability)
|
||||
|
||||
### Self-Observability
|
||||
### Observability
|
||||
|
||||
The SDK provides a self-observability feature that allows you to monitor the SDK itself.
|
||||
The SDK can be configured to provide observability about itself using OpenTelemetry metrics.
|
||||
|
||||
To opt-in, set the environment variable `OTEL_GO_X_SELF_OBSERVABILITY` to `true`.
|
||||
To opt-in, set the environment variable `OTEL_GO_X_OBSERVABILITY` to `true`.
|
||||
|
||||
When enabled, the SDK will create the following metrics using the global `MeterProvider`:
|
||||
|
||||
|
||||
@@ -9,37 +9,44 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// SelfObservability is an experimental feature flag that determines if SDK
|
||||
// self-observability metrics are enabled.
|
||||
// Observability is an experimental feature flag that determines if SDK
|
||||
// observability metrics are enabled.
|
||||
//
|
||||
// To enable this feature set the OTEL_GO_X_SELF_OBSERVABILITY environment variable
|
||||
// To enable this feature set the OTEL_GO_X_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.EqualFold(v, "true") {
|
||||
return v, true
|
||||
}
|
||||
return "", false
|
||||
})
|
||||
var Observability = newFeature(
|
||||
[]string{"OBSERVABILITY", "SELF_OBSERVABILITY"},
|
||||
func(v string) (string, bool) {
|
||||
if strings.EqualFold(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
|
||||
keys []string
|
||||
parse func(v string) (T, bool)
|
||||
}
|
||||
|
||||
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
|
||||
@@ -49,11 +56,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.
|
||||
|
||||
@@ -10,15 +10,18 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestSelfObservability(t *testing.T) {
|
||||
const key = "OTEL_GO_X_SELF_OBSERVABILITY"
|
||||
require.Equal(t, key, SelfObservability.Key())
|
||||
func TestObservability(t *testing.T) {
|
||||
const key = "OTEL_GO_X_OBSERVABILITY"
|
||||
require.Contains(t, Observability.Keys(), 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)))
|
||||
const altKey = "OTEL_GO_X_SELF_OBSERVABILITY"
|
||||
require.Contains(t, Observability.Keys(), altKey)
|
||||
|
||||
t.Run("100", run(setenv(key, "100"), assertDisabled(Observability)))
|
||||
t.Run("true", run(setenv(key, "true"), assertEnabled(Observability, "true")))
|
||||
t.Run("True", run(setenv(key, "True"), assertEnabled(Observability, "True")))
|
||||
t.Run("false", run(setenv(key, "false"), assertDisabled(Observability)))
|
||||
t.Run("empty", run(assertDisabled(Observability)))
|
||||
}
|
||||
|
||||
func run(steps ...func(*testing.T)) func(*testing.T) {
|
||||
|
||||
@@ -26,7 +26,7 @@ import (
|
||||
|
||||
const (
|
||||
defaultTracerName = "go.opentelemetry.io/otel/sdk/tracer"
|
||||
selfObsScopeName = "go.opentelemetry.io/otel/sdk/trace"
|
||||
obsScopeName = "go.opentelemetry.io/otel/sdk/trace"
|
||||
)
|
||||
|
||||
// tracerProviderConfig.
|
||||
@@ -163,15 +163,15 @@ func (p *TracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.T
|
||||
t, ok := p.namedTracer[is]
|
||||
if !ok {
|
||||
t = &tracer{
|
||||
provider: p,
|
||||
instrumentationScope: is,
|
||||
selfObservabilityEnabled: x.SelfObservability.Enabled(),
|
||||
provider: p,
|
||||
instrumentationScope: is,
|
||||
observabilityEnabled: x.Observability.Enabled(),
|
||||
}
|
||||
if t.selfObservabilityEnabled {
|
||||
if t.observabilityEnabled {
|
||||
var err error
|
||||
t.spanLiveMetric, t.spanStartedMetric, err = newInst()
|
||||
if err != nil {
|
||||
msg := "failed to create self-observability metrics for tracer: %w"
|
||||
msg := "failed to create observability metrics for tracer: %w"
|
||||
err := fmt.Errorf(msg, err)
|
||||
otel.Handle(err)
|
||||
}
|
||||
@@ -203,7 +203,7 @@ func (p *TracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.T
|
||||
|
||||
func newInst() (otelconv.SDKSpanLive, otelconv.SDKSpanStarted, error) {
|
||||
m := otel.GetMeterProvider().Meter(
|
||||
selfObsScopeName,
|
||||
obsScopeName,
|
||||
metric.WithInstrumentationVersion(sdk.Version()),
|
||||
metric.WithSchemaURL(semconv.SchemaURL),
|
||||
)
|
||||
|
||||
@@ -401,18 +401,18 @@ func TestTracerProviderReturnsSameTracer(t *testing.T) {
|
||||
assert.Same(t, t2, t5)
|
||||
}
|
||||
|
||||
func TestTracerProviderSelfObservability(t *testing.T) {
|
||||
func TestTracerProviderObservability(t *testing.T) {
|
||||
handler.Reset()
|
||||
p := NewTracerProvider()
|
||||
|
||||
// Enable self-observability
|
||||
t.Setenv("OTEL_GO_X_SELF_OBSERVABILITY", "true")
|
||||
// Enable observability
|
||||
t.Setenv("OTEL_GO_X_OBSERVABILITY", "true")
|
||||
|
||||
tr := p.Tracer("test-tracer")
|
||||
require.IsType(t, &tracer{}, tr)
|
||||
|
||||
tStruct := tr.(*tracer)
|
||||
assert.True(t, tStruct.selfObservabilityEnabled, "Self-observability should be enabled")
|
||||
assert.True(t, tStruct.observabilityEnabled, "observability should be enabled")
|
||||
|
||||
// Verify instruments are created
|
||||
assert.NotNil(t, tStruct.spanLiveMetric, "spanLiveMetric should be created")
|
||||
@@ -423,7 +423,7 @@ func TestTracerProviderSelfObservability(t *testing.T) {
|
||||
assert.Empty(t, handlerErrs, "No errors should occur during instrument creation")
|
||||
}
|
||||
|
||||
func TestTracerProviderSelfObservabilityErrorsHandled(t *testing.T) {
|
||||
func TestTracerProviderObservabilityErrorsHandled(t *testing.T) {
|
||||
handler.Reset()
|
||||
|
||||
orig := otel.GetMeterProvider()
|
||||
@@ -432,8 +432,8 @@ func TestTracerProviderSelfObservabilityErrorsHandled(t *testing.T) {
|
||||
|
||||
p := NewTracerProvider()
|
||||
|
||||
// Enable self-observability
|
||||
t.Setenv("OTEL_GO_X_SELF_OBSERVABILITY", "true")
|
||||
// Enable observability
|
||||
t.Setenv("OTEL_GO_X_OBSERVABILITY", "true")
|
||||
|
||||
// Create a tracer to trigger instrument creation.
|
||||
tr := p.Tracer("test-tracer")
|
||||
|
||||
@@ -496,7 +496,7 @@ func (s *recordingSpan) End(options ...trace.SpanEndOption) {
|
||||
}
|
||||
s.mu.Unlock()
|
||||
|
||||
if s.tracer.selfObservabilityEnabled {
|
||||
if s.tracer.observabilityEnabled {
|
||||
defer func() {
|
||||
// Add the span to the context to ensure the metric is recorded
|
||||
// with the correct span context.
|
||||
|
||||
@@ -408,9 +408,9 @@ func BenchmarkSpanEnd(b *testing.B) {
|
||||
name: "Default",
|
||||
},
|
||||
{
|
||||
name: "SelfObservabilityEnabled",
|
||||
name: "ObservabilityEnabled",
|
||||
env: map[string]string{
|
||||
"OTEL_GO_X_SELF_OBSERVABILITY": "True",
|
||||
"OTEL_GO_X_OBSERVABILITY": "True",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -2246,7 +2246,7 @@ func TestAddLinkToNonRecordingSpan(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSelfObservability(t *testing.T) {
|
||||
func TestObservability(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
test func(t *testing.T, scopeMetrics func() metricdata.ScopeMetrics)
|
||||
@@ -2723,7 +2723,7 @@ func TestSelfObservability(t *testing.T) {
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Setenv("OTEL_GO_X_SELF_OBSERVABILITY", "True")
|
||||
t.Setenv("OTEL_GO_X_OBSERVABILITY", "True")
|
||||
prev := otel.GetMeterProvider()
|
||||
t.Cleanup(func() { otel.SetMeterProvider(prev) })
|
||||
|
||||
@@ -2749,8 +2749,8 @@ type ctxKeyT string
|
||||
// ctxKey is a context key used to store and retrieve values in the context.
|
||||
var ctxKey = ctxKeyT("testKey")
|
||||
|
||||
func TestSelfObservabilityContextPropagation(t *testing.T) {
|
||||
t.Setenv("OTEL_GO_X_SELF_OBSERVABILITY", "True")
|
||||
func TestObservabilityContextPropagation(t *testing.T) {
|
||||
t.Setenv("OTEL_GO_X_OBSERVABILITY", "True")
|
||||
prev := otel.GetMeterProvider()
|
||||
t.Cleanup(func() { otel.SetMeterProvider(prev) })
|
||||
|
||||
@@ -2805,7 +2805,7 @@ func TestSelfObservabilityContextPropagation(t *testing.T) {
|
||||
tp := NewTracerProvider()
|
||||
|
||||
wrap := func(parentCtx context.Context, name string, fn func(context.Context)) {
|
||||
const tracer = "TestSelfObservabilityContextPropagation"
|
||||
const tracer = "TestObservabilityContextPropagation"
|
||||
ctx, s := tp.Tracer(tracer).Start(parentCtx, name)
|
||||
defer s.End()
|
||||
fn(ctx)
|
||||
@@ -2903,9 +2903,9 @@ func BenchmarkTraceStart(b *testing.B) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "SelfObservabilityEnabled",
|
||||
name: "ObservabilityEnabled",
|
||||
env: map[string]string{
|
||||
"OTEL_GO_X_SELF_OBSERVABILITY": "True",
|
||||
"OTEL_GO_X_OBSERVABILITY": "True",
|
||||
},
|
||||
},
|
||||
} {
|
||||
|
||||
@@ -20,9 +20,9 @@ type tracer struct {
|
||||
provider *TracerProvider
|
||||
instrumentationScope instrumentation.Scope
|
||||
|
||||
selfObservabilityEnabled bool
|
||||
spanLiveMetric otelconv.SDKSpanLive
|
||||
spanStartedMetric otelconv.SDKSpanStarted
|
||||
observabilityEnabled bool
|
||||
spanLiveMetric otelconv.SDKSpanLive
|
||||
spanStartedMetric otelconv.SDKSpanStarted
|
||||
}
|
||||
|
||||
var _ trace.Tracer = &tracer{}
|
||||
@@ -53,7 +53,7 @@ func (tr *tracer) Start(
|
||||
|
||||
s := tr.newSpan(ctx, name, &config)
|
||||
newCtx := trace.ContextWithSpan(ctx, s)
|
||||
if tr.selfObservabilityEnabled {
|
||||
if tr.observabilityEnabled {
|
||||
psc := trace.SpanContextFromContext(ctx)
|
||||
set := spanStartedSet(psc, s)
|
||||
tr.spanStartedMetric.AddSet(newCtx, 1, set)
|
||||
@@ -168,7 +168,7 @@ func (tr *tracer) newRecordingSpan(
|
||||
s.SetAttributes(sr.Attributes...)
|
||||
s.SetAttributes(config.Attributes()...)
|
||||
|
||||
if tr.selfObservabilityEnabled {
|
||||
if tr.observabilityEnabled {
|
||||
// Propagate any existing values from the context with the new span to
|
||||
// the measurement context.
|
||||
ctx = trace.ContextWithSpan(ctx, s)
|
||||
|
||||
Reference in New Issue
Block a user