Skip to content

Commit

Permalink
Add confighttp.WithOtelHTTPOptions
Browse files Browse the repository at this point in the history
Signed-off-by: Yuri Shkuro <[email protected]>
  • Loading branch information
yurishkuro committed Nov 28, 2024
1 parent f25fd8d commit 6c102f2
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 12 deletions.
25 changes: 25 additions & 0 deletions .chloggen/withotelhttpoption.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Use this changelog template to create an entry for release notes.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: "enhancement"

# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver)
component: confighttp

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: "Add WithOtelHTTPOptions to confighttp.ToServerOption"

# One or more tracking issues or pull requests related to the change
issues: [11770]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext:

# Optional: The change log or logs in which this entry should be included.
# e.g. '[user]' or '[user, api]'
# Include 'user' if the change is relevant to end users.
# Include 'api' if there is a change to a library API.
# Default: '[user]'
change_logs: []
31 changes: 21 additions & 10 deletions config/confighttp/confighttp.go
Original file line number Diff line number Diff line change
Expand Up @@ -377,8 +377,9 @@ func (hss *ServerConfig) ToListener(ctx context.Context) (net.Listener, error) {
// toServerOptions has options that change the behavior of the HTTP server
// returned by ServerConfig.ToServer().
type toServerOptions struct {
errHandler func(w http.ResponseWriter, r *http.Request, errorMsg string, statusCode int)
decoders map[string]func(body io.ReadCloser) (io.ReadCloser, error)
errHandler func(w http.ResponseWriter, r *http.Request, errorMsg string, statusCode int)
decoders map[string]func(body io.ReadCloser) (io.ReadCloser, error)
otelhttpOpts []otelhttp.Option
}

// ToServerOption is an option to change the behavior of the HTTP server
Expand Down Expand Up @@ -412,6 +413,14 @@ func WithDecoder(key string, dec func(body io.ReadCloser) (io.ReadCloser, error)
})
}

// WithOtelHTTPOptions allows providing (or overriding) options passed
// to the otelhttp.NewHandler() function.
func WithOtelHTTPOptions(httpopts ...otelhttp.Option) ToServerOption {
return toServerOptionFunc(func(opts *toServerOptions) {
opts.otelhttpOpts = append(opts.otelhttpOpts, httpopts...)
})
}

// ToServer creates an http.Server from settings object.
func (hss *ServerConfig) ToServer(_ context.Context, host component.Host, settings component.TelemetrySettings, handler http.Handler, opts ...ToServerOption) (*http.Server, error) {
internal.WarnOnUnspecifiedHost(settings.Logger, hss.Endpoint)
Expand Down Expand Up @@ -461,14 +470,16 @@ func (hss *ServerConfig) ToServer(_ context.Context, host component.Host, settin
handler = responseHeadersHandler(handler, hss.ResponseHeaders)
}

otelOpts := []otelhttp.Option{
otelhttp.WithTracerProvider(settings.TracerProvider),
otelhttp.WithPropagators(otel.GetTextMapPropagator()),
otelhttp.WithSpanNameFormatter(func(_ string, r *http.Request) string {
return r.URL.Path
}),
otelhttp.WithMeterProvider(getLeveledMeterProvider(settings)),
}
otelOpts := append(
[]otelhttp.Option{
otelhttp.WithTracerProvider(settings.TracerProvider),
otelhttp.WithPropagators(otel.GetTextMapPropagator()),
otelhttp.WithSpanNameFormatter(func(_ string, r *http.Request) string {
return r.URL.Path
}),
otelhttp.WithMeterProvider(getLeveledMeterProvider(settings)),
},
serverOpts.otelhttpOpts...)

// Enable OpenTelemetry observability plugin.
// TODO: Consider to use component ID string as prefix for all the operations.
Expand Down
55 changes: 55 additions & 0 deletions config/confighttp/confighttp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ import (

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
"go.opentelemetry.io/otel/sdk/trace/tracetest"
"go.opentelemetry.io/otel/trace"
"go.uber.org/zap"
"go.uber.org/zap/zaptest/observer"

Expand Down Expand Up @@ -1325,6 +1329,57 @@ func TestServerWithDecompression(t *testing.T) {
assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
}

func TestServerWithOtelHTTPOptions(t *testing.T) {
// prepare
hss := ServerConfig{
Endpoint: "localhost:0",
}

telemetry := componenttest.NewNopTelemetrySettings()
tp, te := tracerProvider(t)
telemetry.TracerProvider = tp

srv, err := hss.ToServer(
context.Background(),
componenttest.NewNopHost(),
telemetry,
http.HandlerFunc(func(http.ResponseWriter, *http.Request) {}),
WithOtelHTTPOptions(
otelhttp.WithSpanNameFormatter(func(_ string, r *http.Request) string {
return "example" + r.URL.Path
}),
otelhttp.WithFilter(func(r *http.Request) bool {
return r.URL.Path != "/foobar"
}),
),
)
require.NoError(t, err)

for _, path := range []string{"/path", "/foobar"} {
response := &httptest.ResponseRecorder{}
req, err := http.NewRequest(http.MethodGet, srv.Addr+path, nil)
require.NoError(t, err)
srv.Handler.ServeHTTP(response, req)
assert.Equal(t, http.StatusOK, response.Result().StatusCode)
}

spans := te.GetSpans().Snapshots()
assert.Len(t, spans, 1, "second request should not be traced")
assert.Equal(t, "example/path", spans[0].Name())
}

func tracerProvider(t *testing.T) (trace.TracerProvider, *tracetest.InMemoryExporter) {
exporter := tracetest.NewInMemoryExporter()
tp := sdktrace.NewTracerProvider(
sdktrace.WithSampler(sdktrace.AlwaysSample()),
sdktrace.WithSyncer(exporter),
)
t.Cleanup(func() {
assert.NoError(t, tp.Shutdown(context.Background()))
})
return tp, exporter
}

func TestDefaultMaxRequestBodySize(t *testing.T) {
tests := []struct {
name string
Expand Down
4 changes: 2 additions & 2 deletions config/confighttp/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ require (
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0
go.opentelemetry.io/otel v1.32.0
go.opentelemetry.io/otel/metric v1.32.0
go.opentelemetry.io/otel/sdk v1.32.0
go.opentelemetry.io/otel/trace v1.32.0
go.uber.org/goleak v1.3.0
go.uber.org/zap v1.27.0
golang.org/x/net v0.31.0
Expand All @@ -38,9 +40,7 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
go.opentelemetry.io/collector/extension v0.114.0 // indirect
go.opentelemetry.io/collector/pdata v1.20.0 // indirect
go.opentelemetry.io/otel/sdk v1.32.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.32.0 // indirect
go.opentelemetry.io/otel/trace v1.32.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/sys v0.27.0 // indirect
golang.org/x/text v0.20.0 // indirect
Expand Down

0 comments on commit 6c102f2

Please sign in to comment.