fix otel http instrumentation span naming #2
@@ -10,6 +10,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -27,6 +28,7 @@ import (
|
|||||||
var (
|
var (
|
||||||
httpMeter metric.Meter
|
httpMeter metric.Meter
|
||||||
httpTracer trace.Tracer
|
httpTracer trace.Tracer
|
||||||
|
httpPatternWithMethodRegexp = regexp.MustCompile(`(\w+) .*`)
|
||||||
defReadTimeout = 10 * time.Second
|
defReadTimeout = 10 * time.Second
|
||||||
defWriteTimeout = 10 * time.Second
|
defWriteTimeout = 10 * time.Second
|
||||||
defIdleTimeout = 15 * time.Second
|
defIdleTimeout = 15 * time.Second
|
||||||
@@ -39,19 +41,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 +69,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 +84,18 @@ func prepHTTPServer(opts *opts.AppHTTP) *http.Server {
|
|||||||
default:
|
default:
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
}),
|
||||||
|
otelhttp.WithSpanNameFormatter(func(operation string, r *http.Request) string {
|
||||||
|
endpoint := r.URL.Path
|
||||||
|
if _, pattern := mux.Handler(r); pattern != "" {
|
||||||
|
endpoint = pattern
|
||||||
|
}
|
||||||
|
|
||||||
|
if httpPatternWithMethodRegexp.MatchString(endpoint) {
|
||||||
|
return endpoint
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("%s %s", r.Method, endpoint)
|
||||||
}))
|
}))
|
||||||
|
|
||||||
// Set timeouts from defaults, override
|
// Set timeouts from defaults, override
|
||||||
|
Reference in New Issue
Block a user