Naar hoofdinhoud gaan
Gorilla Mux is een populaire request-router en dispatcher voor de Go-taal.
Dit project is in december 2022 uit onderhoud genomen en wordt niet meer ondersteund. Wij weten echter dat dit een populaire tool is binnen de Go-community, en het zal even duren voordat gebruikers hun apps naar een nieuwe tool migreren. Daarom bieden wij ondersteuning voor Gorilla Mux-apps, zodat u waardevolle informatie uit uw services krijgt totdat u een geschikt alternatief hebt gevonden.

Setup

Om uw Gorilla Mux-applicatie te instrumenteren, importeert u het officiële OpenTelemetry-instrumentatiepakket:
import "go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux"
De Gorilla Mux-instrumentatie is verpakt als router-middleware. Zoals u in het onderstaande voorbeeld kunt zien, wordt de initialisatie van de tracer eerst aangeroepen, zoals uitgebreider beschreven in de sectie Go-configuratie. U hoeft alleen otelmux.Middleware() toe te voegen aan uw app-router om al uw requests te laten instrumenteren.
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
	// ...
}

Request-parameters rapporteren

Standaard rapporteert de Gorilla-instrumentatie geen inkomende request-parameters, zoals query strings en JSON body-inhoud. Voeg de volgende middleware toe aan uw Gorilla-stack om deze waarden naar AppSignal te rapporteren:
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...
}