Gorilla Mux Instrumentation
Gorilla Mux is a popular request router and dispatcher for the Go language.
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, ¶ms) 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... }