kra-oa/internal/server/middleware/request.go

49 lines
1.3 KiB
Go

package middleware
import (
"crypto/rand"
"encoding/hex"
"regexp"
"strings"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
)
var traceParentPattern = regexp.MustCompile(`^00-([0-9a-f]{32})-([0-9a-f]{16})-[0-9a-f]{2}$`)
func randomHex(bytes int) string {
value := make([]byte, bytes)
_, _ = rand.Read(value)
return hex.EncodeToString(value)
}
func RequestMeta() gin.HandlerFunc {
return func(c *gin.Context) {
requestID := c.GetHeader("X-Request-Id")
if requestID == "" || len(requestID) > 128 || strings.ContainsAny(requestID, "\r\n") {
requestID = uuid.NewString()
}
traceID, parentSpanID := "", ""
if match := traceParentPattern.FindStringSubmatch(strings.ToLower(c.GetHeader("traceparent"))); len(match) == 3 {
traceID, parentSpanID = match[1], match[2]
} else if candidate := c.GetHeader("X-Trace-Id"); len(candidate) <= 128 && !strings.ContainsAny(candidate, "\r\n") {
traceID = candidate
}
if traceID == "" {
traceID = randomHex(16)
}
spanID := randomHex(8)
c.Header("X-Request-Id", requestID)
c.Header("X-Trace-Id", traceID)
if len(traceID) == 32 {
c.Header("traceparent", "00-"+traceID+"-"+spanID+"-01")
}
c.Set("request_id", requestID)
c.Set("trace_id", traceID)
c.Set("span_id", spanID)
c.Set("parent_span_id", parentSpanID)
c.Next()
}
}