Pular para o conteúdo principal
O Gorilla Mux é um popular roteador e dispatcher de requisições para a linguagem Go.
Este projeto foi descontinuado em dezembro de 2022 e não recebe mais suporte; no entanto, sabemos que essa ainda é uma ferramenta popular na comunidade Go, e levará um tempo até que os usuários migrem suas aplicações para uma nova ferramenta. Por isso, fornecemos suporte para aplicações Gorilla Mux, para que você obtenha informações valiosas dos seus serviços até encontrar um substituto adequado.

Configuração

Para instrumentar sua aplicação Gorilla Mux, você precisará importar o pacote oficial de instrumentação do OpenTelemetry:
import "go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux"
A instrumentação do Gorilla Mux é distribuída como um middleware de roteador. Como você pode ver no exemplo abaixo, a inicialização do tracer é chamada antes de qualquer coisa, conforme descrito em mais detalhes na seção Configuração do Go. Adicionar otelmux.Middleware() ao roteador da sua aplicação é tudo o que você precisa para ter todas as suas requisições instrumentadas.
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
	// ...
}

Reportar parâmetros de requisição

Por padrão, a instrumentação do Gorilla não reporta nenhum parâmetro de requisição recebida, como query strings e conteúdo de corpo JSON. Para reportar esses valores ao AppSignal, adicione um middleware à sua stack Gorilla da seguinte forma:
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...
}