| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -10,6 +10,7 @@ import (
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					"net"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					"net/http"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					"os"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					"regexp"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					"strings"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					"time"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -27,6 +28,7 @@ import (
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				var (
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					httpMeter                   metric.Meter
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					httpTracer                  trace.Tracer
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					httpPatternWithMethodRegexp = regexp.MustCompile(`(\w+) .*`)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					defReadTimeout              = 10 * time.Second
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					defWriteTimeout             = 10 * time.Second
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					defIdleTimeout              = 15 * time.Second
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -39,19 +41,12 @@ func prepHTTPServer(opts *opts.AppHTTP) *http.Server {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						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...)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					otelHandleFunc("/health", healthChecks)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					otelHandleFunc("/", healthChecks)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					mux.HandleFunc("/health", healthChecks)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					mux.HandleFunc("/", healthChecks)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					for _, f := range opts.Funcs {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						otelHandleFunc(f.Path, f.HandlerFunc)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						mux.HandleFunc(f.Path, f.HandlerFunc)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// Prometheus metrics endpoint
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -74,12 +69,12 @@ func prepHTTPServer(opts *opts.AppHTTP) *http.Server {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if h.StripPrefix {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							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
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// NOTE: Add any other span exclusions here
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// Add OTEL instrumentation, filter noise, set span names
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					handler := otelhttp.NewHandler(mux, "/",
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						// TODO: Make configurable similar to config.http.LogExcludePathRegexps
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						otelhttp.WithFilter(func(r *http.Request) bool {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							switch r.URL.Path {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							case "/health":
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -89,6 +84,18 @@ func prepHTTPServer(opts *opts.AppHTTP) *http.Server {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							default:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								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
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				 
 |