69 lines
2.1 KiB
Go
69 lines
2.1 KiB
Go
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 ""
|
|
}
|