Gorilla Mux Instrumentation

Gorilla Mux is a popular request router and dispatcher for the Go language.

This project was deprecated in December 2022 and is no longer supported, however, we are aware that this is a popular tool among the Go community, and it'll take a while for users to migrate their apps to new tool. That's why we're providing support for Gorilla Mux apps, so you get valuable information from your services until you find a suitable replacement.

Setup

To instrument your Gorilla Mux application, you'll need to import the OpenTelemetry official instrumentation package:

shell
import "go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux"

The Gorilla Mux instrumentation is packaged as a router middleware, as you can see in the example below, the tracer initialization is called before anything as described in more detail in the Go Configuration section. Adding otelmux.Middleware() to your app router is all that you need to get all your requests instrumented.

go
func main() { cleanup := initTracer() defer cleanup(context.Background()) router := mux.NewRouter().StrictSlash(true) // This middleware must be added before any middlewares or routes router.Use(otelmux.Middleware("your-app-name")) // Your routes, app's logic, and server start up // ... }

Reporting request parameters

By default, the Gorilla instrumentation does not report any incoming request parameters, like query strings and JSON body contents.

To report these values to AppSignal, add a middleware to your Gorilla stack as follows:

go
import ( "bytes" "encoding/json" "io/ioutil" "net/http" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" ) func recordParameters(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { span := trace.SpanFromContext(r.Context()) parametersKey := attribute.Key("appsignal.request.parameters") queryParams := r.URL.Query() bodyParams, err := ioutil.ReadAll(r.Body) if err != nil { bodyParams = []byte("{}") } else { r.Body = ioutil.NopCloser(bytes.NewBuffer(bodyParams)) } params := make(map[string]any) json.Unmarshal(bodyParams, &params) for k, v := range queryParams { params[k] = v } if len(params) > 0 { serializedParams, err := json.Marshal(params) if err != nil { next.ServeHTTP(w, r) return } span.SetAttributes(parametersKey.String(string(serializedParams))) } next.ServeHTTP(w, r) }) } func main() { // Init OpenTelemetry cleanup := initTracer() defer cleanup(context.Background()) router := mux.NewRouter().StrictSlash(true) router.Use(otelmux.Middleware("opentelemetry-go-gorillamux")) // After the OpenTelemetry middleware, but before your other middlewares: router.Use(recordParameters) // Other middlewares and router handlers go here... }