package middleware import ( "github.com/gin-gonic/gin" "github.com/google/uuid" ) const ( // TraceIDHeader est le nom du header HTTP pour propager le trace ID TraceIDHeader = "X-Trace-ID" // TraceIDKey est la clé utilisée pour stocker le trace ID dans le contexte Gin TraceIDKey = "trace_id" // SpanIDHeader est le nom du header HTTP pour propager le span ID (optionnel) SpanIDHeader = "X-Span-ID" // SpanIDKey est la clé utilisée pour stocker le span ID dans le contexte Gin SpanIDKey = "span_id" ) // Tracing middleware pour générer et propager trace ID (W3C Trace Context compatible) // Le trace ID permet de tracer une requête à travers plusieurs services // Si un trace ID est déjà présent dans le header, il est réutilisé (propagation) // Sinon, un nouveau trace ID UUID v4 est généré func Tracing() gin.HandlerFunc { return func(c *gin.Context) { // Récupérer ou générer le trace ID traceID := c.GetHeader(TraceIDHeader) if traceID == "" { // Générer un nouveau trace ID UUID v4 (compatible W3C Trace Context) traceID = uuid.New().String() } // Récupérer ou générer le span ID (optionnel, pour corrélation fine) spanID := c.GetHeader(SpanIDHeader) if spanID == "" { // Générer un nouveau span ID UUID v4 spanID = uuid.New().String() } // Stocker dans le contexte Gin pour utilisation dans les handlers et logs c.Set(TraceIDKey, traceID) c.Set(SpanIDKey, spanID) // Propager via les headers de réponse (pour que les clients puissent le réutiliser) c.Header(TraceIDHeader, traceID) c.Header(SpanIDHeader, spanID) c.Next() } } // GetTraceID retourne le trace ID du contexte, ou une chaîne vide si non défini func GetTraceID(c *gin.Context) string { if traceID, exists := c.Get(TraceIDKey); exists { if id, ok := traceID.(string); ok { return id } } return "" } // GetSpanID retourne le span ID du contexte, ou une chaîne vide si non défini func GetSpanID(c *gin.Context) string { if spanID, exists := c.Get(SpanIDKey); exists { if id, ok := spanID.(string); ok { return id } } return "" }