From bcb8a24ed1b61b17460958baadf7da3bc430814b Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 12 Feb 2026 15:38:55 +0100 Subject: [PATCH 1/4] Fix Go lint issues and enable GO_MODULES validation - Fix shadow warning in otel.go (rename inner err to errs) - Fix empty-block warning in rolldice.go (nolint:revive) - Remove deprecated otelhttp.WithRouteTag (auto-extracted since Go 1.22+) - Switch from VALIDATE_GO_MODULES=false to VALIDATE_GO=false (GO_MODULES no longer times out; non-module GO can't handle two modules) - Replace FIX_GO with FIX_GO_MODULES --- .github/config/super-linter.env | 6 +++--- examples/go/main.go | 11 ++--------- examples/go/otel.go | 6 +++--- examples/go/rolldice.go | 2 +- 4 files changed, 9 insertions(+), 16 deletions(-) diff --git a/.github/config/super-linter.env b/.github/config/super-linter.env index 2c587e11..8e7f9397 100644 --- a/.github/config/super-linter.env +++ b/.github/config/super-linter.env @@ -11,8 +11,8 @@ VALIDATE_BIOME_LINT=false VALIDATE_CHECKOV=false VALIDATE_DOCKERFILE_HADOLINT=false VALIDATE_GIT_COMMITLINT=false -# times out -VALIDATE_GO_MODULES=false +# golangci-lint (non-module mode) can't handle two Go modules; GO_MODULES covers this +VALIDATE_GO=false # we have many duplicate code in our codebase for demo purposes VALIDATE_JSCPD=false # conflicts with black @@ -27,8 +27,8 @@ VALIDATE_TRIVY=false FIX_CSHARP=true FIX_ENV=true -FIX_GO=true FIX_GOOGLE_JAVA_FORMAT=true +FIX_GO_MODULES=true FIX_JAVASCRIPT_PRETTIER=true FIX_JSON=true FIX_JSONC=true diff --git a/examples/go/main.go b/examples/go/main.go index 944dee15..88301770 100644 --- a/examples/go/main.go +++ b/examples/go/main.go @@ -66,18 +66,11 @@ func run() (err error) { func newHTTPHandler() http.Handler { mux := http.NewServeMux() - // handleFunc is a replacement for mux.HandleFunc - // which enriches the handler's HTTP instrumentation with the pattern as the http.route. - handleFunc := func(pattern string, handlerFunc func(http.ResponseWriter, *http.Request)) { - // Configure the "http.route" for the HTTP instrumentation. - handler := otelhttp.WithRouteTag(pattern, http.HandlerFunc(handlerFunc)) - mux.Handle(pattern, handler) - } - // Register handlers. - handleFunc("/rolldice", rolldice) + mux.HandleFunc("/rolldice", rolldice) // Add HTTP instrumentation for the whole server. + // Since Go 1.22+, otelhttp automatically extracts the route from ServeMux patterns. handler := otelhttp.NewHandler(mux, "/") return handler } diff --git a/examples/go/otel.go b/examples/go/otel.go index 7cc129c8..ff7a36d1 100644 --- a/examples/go/otel.go +++ b/examples/go/otel.go @@ -37,12 +37,12 @@ func setupOTelSDK(ctx context.Context) (shutdown func(context.Context) error, er // The errors from the calls are joined. // Each registered cleanup will be invoked once. shutdown = func(ctx context.Context) error { - var err error + var errs error for _, fn := range shutdownFuncs { - err = errors.Join(err, fn(ctx)) + errs = errors.Join(errs, fn(ctx)) } shutdownFuncs = nil - return err + return errs } // handleErr calls shutdown for cleanup and makes sure that all errors are returned. diff --git a/examples/go/rolldice.go b/examples/go/rolldice.go index e82857e9..10d54f27 100644 --- a/examples/go/rolldice.go +++ b/examples/go/rolldice.go @@ -39,8 +39,8 @@ func roll() int { // simulate a long operation // busy wait to make sure it's shown in the flame graph start := time.Now() + //nolint:revive // intentional busy wait for flame graph demo for time.Since(start) < 1*time.Second { - // busy wait } //nolint:gosec From 38a5d4b2fb0dac42f7e60e776cf4517b9d8a31a7 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 12 Feb 2026 18:00:48 +0100 Subject: [PATCH 2/4] Restore otelhttp.WithRouteTag for http.route span attribute The automatic route extraction from http.Request.Pattern does not work in otelhttp v0.64.0 when otelhttp.NewHandler wraps a ServeMux: the http.route attribute is read at span creation time, before the ServeMux has routed the request and populated r.Pattern. This caused the oats acceptance test to fail because the TraceQL query for http.route returned no traces. --- examples/go/main.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/examples/go/main.go b/examples/go/main.go index 88301770..db4b185e 100644 --- a/examples/go/main.go +++ b/examples/go/main.go @@ -66,11 +66,23 @@ func run() (err error) { func newHTTPHandler() http.Handler { mux := http.NewServeMux() + // handleFunc is a replacement for mux.HandleFunc + // which enriches the handler's HTTP instrumentation with the pattern as the http.route. + // + // NOTE: otelhttp.WithRouteTag is marked deprecated, claiming that http.route is + // automatically extracted from http.Request.Pattern (Go 1.22+). However, as of + // otelhttp v0.64.0 this does not work when otelhttp wraps a ServeMux: the + // http.route attribute is read at span creation time, before the ServeMux has + // routed the request and populated r.Pattern. WithRouteTag is still needed. + handleFunc := func(pattern string, handlerFunc func(http.ResponseWriter, *http.Request)) { + handler := otelhttp.WithRouteTag(pattern, http.HandlerFunc(handlerFunc)) + mux.Handle(pattern, handler) + } + // Register handlers. - mux.HandleFunc("/rolldice", rolldice) + handleFunc("/rolldice", rolldice) // Add HTTP instrumentation for the whole server. - // Since Go 1.22+, otelhttp automatically extracts the route from ServeMux patterns. handler := otelhttp.NewHandler(mux, "/") return handler } From be02fa1e899550fd470c27af0f7d4b7665ce0bc4 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 12 Feb 2026 18:11:41 +0100 Subject: [PATCH 3/4] Suppress staticcheck deprecation warning for WithRouteTag --- examples/go/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/go/main.go b/examples/go/main.go index db4b185e..3320a2a1 100644 --- a/examples/go/main.go +++ b/examples/go/main.go @@ -75,7 +75,7 @@ func newHTTPHandler() http.Handler { // http.route attribute is read at span creation time, before the ServeMux has // routed the request and populated r.Pattern. WithRouteTag is still needed. handleFunc := func(pattern string, handlerFunc func(http.ResponseWriter, *http.Request)) { - handler := otelhttp.WithRouteTag(pattern, http.HandlerFunc(handlerFunc)) + handler := otelhttp.WithRouteTag(pattern, http.HandlerFunc(handlerFunc)) //nolint:staticcheck // see comment above mux.Handle(pattern, handler) } From d6a802ab6dbaf648d147618fb5767b06152fc9ff Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 12 Feb 2026 18:14:52 +0100 Subject: [PATCH 4/4] pr review --- examples/go/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/go/main.go b/examples/go/main.go index 3320a2a1..09e36bf3 100644 --- a/examples/go/main.go +++ b/examples/go/main.go @@ -75,7 +75,7 @@ func newHTTPHandler() http.Handler { // http.route attribute is read at span creation time, before the ServeMux has // routed the request and populated r.Pattern. WithRouteTag is still needed. handleFunc := func(pattern string, handlerFunc func(http.ResponseWriter, *http.Request)) { - handler := otelhttp.WithRouteTag(pattern, http.HandlerFunc(handlerFunc)) //nolint:staticcheck // see comment above + handler := otelhttp.WithRouteTag(pattern, http.HandlerFunc(handlerFunc)) //nolint:staticcheck mux.Handle(pattern, handler) }