Setup
To instrument your Gorilla Mux application, you’ll need to import the OpenTelemetry official instrumentation package:otelmux.Middleware() to your app router is all that you need to get all your requests instrumented.
Documentation Index
Fetch the complete documentation index at: /llms.txt
Use this file to discover all available pages before exploring further.
import "go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux"
otelmux.Middleware() to your app router is all that you need to get all your requests instrumented.
func main() {
cleanup := initOpenTelemetry()
defer cleanup()
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
// ...
}
import (
"bytes"
"encoding/json"
"io/ioutil"
"net/http"
"net/url"
"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())
// Query parameters
requestQueryParameters := r.URL.Query()
attributeQueryParameters := make(map[string]any)
for k, v := range requestQueryParameters {
attributeQueryParameters[k] = v
}
if len(attributeQueryParameters) > 0 {
serializedQueryParams, err := json.Marshal(attributeQueryParameters)
if err == nil {
span.SetAttributes(attribute.String("appsignal.request.query_parameters", string(serializedQueryParams)))
}
}
// Request body payload
var serializedBodyPayload string
var payload map[string]interface{}
requestBodyPayload, err := ioutil.ReadAll(r.Body)
if err != nil {
next.ServeHTTP(w, r)
return
}
r.Body = ioutil.NopCloser(bytes.NewBuffer(requestBodyPayload))
contentType := r.Header.Get("Content-Type")
if contentType == "application/json" {
serializedBodyPayload = string(requestBodyPayload)
} else if contentType == "application/x-www-form-urlencoded" {
// Parse form-urlencoded body
values, err := url.ParseQuery(string(requestBodyPayload))
if err != nil {
next.ServeHTTP(w, r)
return
}
// Convert form values to a JSON-compatible map
payload = make(map[string]interface{})
for key, val := range values {
if len(val) == 1 {
payload[key] = val[0]
} else {
payload[key] = val
}
}
json, _ := json.Marshal(payload)
serializedBodyPayload = string(json)
} else {
next.ServeHTTP(w, r)
return
}
if len(serializedBodyPayload) > 0 {
span.SetAttributes(attribute.String("appsignal.request.payload", serializedBodyPayload))
}
next.ServeHTTP(w, r)
})
}
func main() {
// Init OpenTelemetry
cleanup := initOpenTelemetry()
defer cleanup()
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...
}
Was this page helpful?