Files
portal-mini-go/internal/middleware/trace.go
T
2026-10-25 20:27:59 +08:00

54 lines
1.1 KiB
Go

package middleware
import (
"crypto/rand"
"encoding/hex"
"log/slog"
"github.com/gin-gonic/gin"
)
const traceIDKey = "trace_id"
// Trace 透传或生成 trace_id,并注入可携带 trace_id 的 slog 日志句柄,
// 供后续日志统一携带链路标识。
func Trace() gin.HandlerFunc {
return func(c *gin.Context) {
tid := c.GetHeader("X-Trace-ID")
if tid == "" {
tid = newTraceID()
}
c.Set(traceIDKey, tid)
c.Set("slog_ctx", slog.With(slog.String("trace_id", tid)))
c.Next()
}
}
func newTraceID() string {
b := make([]byte, 16)
if _, err := rand.Read(b); err != nil {
return "unknown"
}
return hex.EncodeToString(b)
}
// TraceID 从 gin.Context 取出 trace_id。
func TraceID(c *gin.Context) string {
if v, ok := c.Get(traceIDKey); ok {
if s, ok := v.(string); ok {
return s
}
}
return ""
}
// SlogCtx 返回携带 trace_id 的 slog 日志句柄(无则回退默认)。
func SlogCtx(c *gin.Context) *slog.Logger {
if v, ok := c.Get("slog_ctx"); ok {
if l, ok := v.(*slog.Logger); ok {
return l
}
}
return slog.Default()
}