> ## Documentation Index
> Fetch the complete documentation index at: https://docs.appsignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Instrumentation Gin-gonic

[Gin-gonic](https://gin-gonic.com) est un framework web complet pour Go.
Les données reportées depuis Gin-gonic sont prises en charge par AppSignal.

Cette page vous aidera à configurer l'instrumentation des applications Gin-gonic et à reporter les paramètres et payloads de requête.

## Configuration

Pour instrumenter votre application Go-gin, vous devrez importer le paquet d'instrumentation officiel OpenTelemetry :

<CodeGroup>
  ```go Go theme={null}
  import "go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin"
  ```
</CodeGroup>

L'instrumentation Go-gin est packagée comme un middleware de routeur. Comme vous pouvez le voir dans l'exemple ci-dessous, l'initialisation du tracer est appelée avant tout autre chose, comme décrit plus en détail sur la page [Installation Go](/go/installation). Ajouter `otelgin.Middleware()` au routeur de votre application est tout ce dont vous avez besoin pour instrumenter toutes vos requêtes.

<CodeGroup>
  ```go Go theme={null}
  func main() {
  	cleanup := initOpenTelemetry()
  	defer cleanup()

  	router := gin.New()
  	// This middleware must be added before any middlewares or routes
  	router.Use(otelgin.Middleware("your-app-name"))
  	// Your routes, app's logic, and server start up
  	// ...
  }
  ```
</CodeGroup>

## Reporter les paramètres de requête

Par défaut, l'instrumentation Gin ne reporte aucun paramètre de requête entrant, comme les chaînes de requête et le contenu du corps JSON.

Pour reporter ces valeurs à AppSignal, ajoutez un middleware à votre stack Gin-gonic comme suit :

<CodeGroup>
  ```go Go theme={null}
  import (
  	"bytes"
  	"encoding/json"
  	"context"
  	"io/ioutil"
  	"net/url"

  	"github.com/gin-gonic/gin"
  	"go.opentelemetry.io/otel/attribute"
  	"go.opentelemetry.io/otel/trace"
  )

  func recordParameters(c *gin.Context) {
  	span := trace.SpanFromContext(c.Request.Context())

  	// Query parameters
  	requestQueryParameters := c.Request.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(c.Request.Body)
  	if err != nil {
  		c.Next()
  		return
  	}
  	c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(requestBodyPayload))
  	contentType := c.GetHeader("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 {
  			c.Next()
  			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 {
  		c.Next()
  		return
  	}
  	if len(serializedBodyPayload) > 0 {
  		span.SetAttributes(attribute.String("appsignal.request.payload", serializedBodyPayload))
  	}
  	c.Next()
  }

  func main() {
  	// Init OpenTelemetry
  	cleanup := initOpenTelemetry()
  	defer cleanup()

  	r := gin.New()
  	r.Use(otelgin.Middleware("opentelemetry-go-gin"))
  	// After the OpenTelemetry middleware, but before your other middlewares:
  	r.Use(recordParameters)
  	// Other middlewares and router handlers go here...
  }
  ```
</CodeGroup>
