|
|
@@ -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
|
|
|
|