Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(autoexport): change WithFallback options signatures #4891

Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Expand Up @@ -14,6 +14,12 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Add client metric support to `go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp`. (#4707)
- Add peer attributes to spans recorded by `NewClientHandler`, `NewServerHandler` in `go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc`. (#4873)

### Changed

- The fallback options in `go.opentelemetry.io/contrib/exporters/autoexport` now accept factory functions. (#4891)
- `WithFallbackMetricReader(metric.Reader) MetricOption` is replaced with `func WithFallbackMetricReader(func(ctx context.Context) (metric.Reader, error)) MetricOption`.
- `WithFallbackSpanExporter(trace.SpanExporter) SpanOption` is replaced with `WithFallbackSpanExporter(func(ctx context.Context) (trace.SpanExporter, error)) SpanOption`.

### Deprecated

- The `RequestCount`, `RequestContentLength`, `ResponseContentLength`, `ServerLatency` constants in `go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp` are deprecated. (#4707)
Expand Down
4 changes: 2 additions & 2 deletions exporters/autoexport/metrics.go
Expand Up @@ -39,8 +39,8 @@ type MetricOption = option[metric.Reader]

// WithFallbackMetricReader sets the fallback exporter to use when no exporter
// is configured through the OTEL_METRICS_EXPORTER environment variable.
func WithFallbackMetricReader(exporter metric.Reader) MetricOption {
return withFallback[metric.Reader](exporter)
func WithFallbackMetricReader(metricReaderFactory func(ctx context.Context) (metric.Reader, error)) MetricOption {
return withFallbackFactory[metric.Reader](metricReaderFactory)
}

// NewMetricReader returns a configured [go.opentelemetry.io/otel/sdk/metric.Reader]
Expand Down
10 changes: 5 additions & 5 deletions exporters/autoexport/signal.go
Expand Up @@ -42,7 +42,7 @@ func (s signal[T]) create(ctx context.Context, opts ...option[T]) (T, error) {
expType := os.Getenv(s.envKey)
if expType == "" {
if cfg.hasFallback {
return cfg.fallback, nil
return cfg.fallbackFactory(ctx)
}
expType = "otlp"
}
Expand All @@ -51,8 +51,8 @@ func (s signal[T]) create(ctx context.Context, opts ...option[T]) (T, error) {
}

type config[T any] struct {
hasFallback bool
fallback T
hasFallback bool
hcelaloner marked this conversation as resolved.
Show resolved Hide resolved
fallbackFactory func(ctx context.Context) (T, error)
}

type option[T any] interface {
Expand All @@ -66,9 +66,9 @@ func (fn optionFunc[T]) apply(cfg *config[T]) {
fn(cfg)
}

func withFallback[T any](fallback T) option[T] {
func withFallbackFactory[T any](fallbackFactory func(ctx context.Context) (T, error)) option[T] {
return optionFunc[T](func(cfg *config[T]) {
cfg.hasFallback = true
cfg.fallback = fallback
cfg.fallbackFactory = fallbackFactory
})
}
21 changes: 16 additions & 5 deletions exporters/autoexport/signal_test.go
Expand Up @@ -16,6 +16,7 @@ package autoexport // import "go.opentelemetry.io/contrib/exporters/autoexport"

import (
"context"
"errors"
"testing"

"github.com/stretchr/testify/assert"
Expand All @@ -31,10 +32,21 @@ func TestOTLPExporterReturnedWhenNoEnvOrFallbackExporterConfigured(t *testing.T)

func TestFallbackExporterReturnedWhenNoEnvExporterConfigured(t *testing.T) {
ts := newSignal[*testType]("TEST_TYPE_KEY")
fallback := testType{"test-fallback-exporter"}
exp, err := ts.create(context.Background(), withFallback(&fallback))
exp, err := ts.create(context.Background(), withFallbackFactory(factory("test-fallback-exporter")))
assert.NoError(t, err)
assert.Same(t, &fallback, exp)
assert.Equal(t, exp.string, "test-fallback-exporter")
}

func TestFallbackExporterFactoryErrorReturnedWhenNoEnvExporterConfiguredAndFallbackFactoryReturnsAnError(t *testing.T) {
ts := newSignal[*testType]("TEST_TYPE_KEY")

expectedErr := errors.New("error expected to return")
errFactory := func(ctx context.Context) (*testType, error) {
return nil, expectedErr
}
exp, err := ts.create(context.Background(), withFallbackFactory(errFactory))
assert.ErrorIs(t, err, expectedErr)
assert.Nil(t, exp)
}

func TestEnvExporterIsPreferredOverFallbackExporter(t *testing.T) {
Expand All @@ -43,10 +55,9 @@ func TestEnvExporterIsPreferredOverFallbackExporter(t *testing.T) {

expName := "test-env-exporter-name"
t.Setenv(envVariable, expName)
fallback := testType{"test-fallback-exporter"}
assert.NoError(t, ts.registry.store(expName, factory("test-env-exporter")))

exp, err := ts.create(context.Background(), withFallback(&fallback))
exp, err := ts.create(context.Background(), withFallbackFactory(factory("test-fallback-exporter")))
assert.NoError(t, err)
assert.Equal(t, exp.string, "test-env-exporter")
}
4 changes: 2 additions & 2 deletions exporters/autoexport/spans.go
Expand Up @@ -34,8 +34,8 @@ type Option = SpanOption

// WithFallbackSpanExporter sets the fallback exporter to use when no exporter
// is configured through the OTEL_TRACES_EXPORTER environment variable.
func WithFallbackSpanExporter(exporter trace.SpanExporter) SpanOption {
return withFallback[trace.SpanExporter](exporter)
func WithFallbackSpanExporter(spanExporterFactory func(ctx context.Context) (trace.SpanExporter, error)) SpanOption {
return withFallbackFactory[trace.SpanExporter](spanExporterFactory)
}

// NewSpanExporter returns a configured [go.opentelemetry.io/otel/sdk/trace.SpanExporter]
Expand Down