refactors OpenTelemetry HTTP instrumentation by centralizing handler wrapping, adding span name formatting, and filtering health and metrics paths.
This commit is contained in:
@@ -39,19 +39,12 @@ func prepHTTPServer(opts *opts.AppHTTP) *http.Server {
|
|||||||
mux = &http.ServeMux{}
|
mux = &http.ServeMux{}
|
||||||
)
|
)
|
||||||
|
|
||||||
// NOTE: Wraps handle func with otelhttp handler and
|
|
||||||
// inserts route tag
|
|
||||||
otelHandleFunc := func(pattern string, handlerFunc func(http.ResponseWriter, *http.Request)) {
|
|
||||||
handler := otelhttp.WithRouteTag(pattern, http.HandlerFunc(handlerFunc))
|
|
||||||
mux.Handle(pattern, handler) // Associate pattern with handler
|
|
||||||
}
|
|
||||||
|
|
||||||
healthChecks := handleHealthCheckFunc(opts.Ctx, opts.HealthChecks...)
|
healthChecks := handleHealthCheckFunc(opts.Ctx, opts.HealthChecks...)
|
||||||
otelHandleFunc("/health", healthChecks)
|
mux.HandleFunc("/health", healthChecks)
|
||||||
otelHandleFunc("/", healthChecks)
|
mux.HandleFunc("/", healthChecks)
|
||||||
|
|
||||||
for _, f := range opts.Funcs {
|
for _, f := range opts.Funcs {
|
||||||
otelHandleFunc(f.Path, f.HandlerFunc)
|
mux.HandleFunc(f.Path, f.HandlerFunc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prometheus metrics endpoint
|
// Prometheus metrics endpoint
|
||||||
@@ -74,12 +67,12 @@ func prepHTTPServer(opts *opts.AppHTTP) *http.Server {
|
|||||||
if h.StripPrefix {
|
if h.StripPrefix {
|
||||||
h.Handler = http.StripPrefix(h.Prefix[:len(h.Prefix)-1], h.Handler)
|
h.Handler = http.StripPrefix(h.Prefix[:len(h.Prefix)-1], h.Handler)
|
||||||
}
|
}
|
||||||
mux.Handle(h.Prefix, h.Handler)
|
mux.Handle(h.Prefix, otelhttp.WithRouteTag(h.Prefix, h.Handler))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add OTEL, skip health-check spans
|
// Add OTEL instrumentation, filter noise, set span names
|
||||||
// NOTE: Add any other span exclusions here
|
|
||||||
handler := otelhttp.NewHandler(mux, "/",
|
handler := otelhttp.NewHandler(mux, "/",
|
||||||
|
// TODO: Make configurable similar to config.http.LogExcludePathRegexps
|
||||||
otelhttp.WithFilter(func(r *http.Request) bool {
|
otelhttp.WithFilter(func(r *http.Request) bool {
|
||||||
switch r.URL.Path {
|
switch r.URL.Path {
|
||||||
case "/health":
|
case "/health":
|
||||||
@@ -89,6 +82,14 @@ func prepHTTPServer(opts *opts.AppHTTP) *http.Server {
|
|||||||
default:
|
default:
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
}),
|
||||||
|
otelhttp.WithSpanNameFormatter(func(operation string, r *http.Request) string {
|
||||||
|
_, pattern := mux.Handler(r)
|
||||||
|
if pattern != "" {
|
||||||
|
return pattern // Use the route pattern as the span name, e.g., "/users/{id}"
|
||||||
|
}
|
||||||
|
// Fallback to the default naming convention if no route is found.
|
||||||
|
return operation + " " + r.URL.Path
|
||||||
}))
|
}))
|
||||||
|
|
||||||
// Set timeouts from defaults, override
|
// Set timeouts from defaults, override
|
||||||
|
Reference in New Issue
Block a user