辅助中间件
请求上下文
RequestContext 为每个请求生成唯一标识符和记录开始时间
请求上下文
RequestContext 为每个 HTTP 请求生成唯一标识符 (UUID) 并记录请求开始时间,用于请求追踪和性能监控。
RequestContext
func RequestContext() gin.HandlerFunc实现:
func RequestContext() gin.HandlerFunc {
return func(c *gin.Context) {
// 1. 生成请求唯一 ID (UUID)
requestID := uuid.NewString()
// 2. 设置响应头 X-Request-UUID
c.Writer.Header().Set(xHttp.HeaderRequestUUID.String(), requestID)
// 3. 存储到 Gin Context
c.Set(xCtx.RequestKey.String(), requestID)
c.Set(xCtx.UserStartTimeKey.String(), time.Now())
// 4. 注入到标准 context (供 slog 日志使用)
ctx := context.WithValue(c.Request.Context(), xCtx.RequestKey, requestID)
c.Request = c.Request.WithContext(ctx)
c.Next()
}
}注入的上下文键
字段
类型
响应头
中间件会在响应头中添加请求 UUID:
X-Request-UUID: 550e8400-e29b-41d4-a716-446655440000使用示例
基础使用
func main() {
router := gin.New()
// 注册请求上下文中间件(应该最先注册)
router.Use(xHelper.RequestContext())
router.GET("/api/users", getUsers)
router.Run(":8080")
}获取请求 UUID
func GetUser(ctx *gin.Context) {
// 从 Gin Context 获取
requestID := ctx.GetString(xCtx.RequestKey.String())
// 用于日志记录
xLog.WithName(xLog.NamedCONT).SugarInfo(ctx, "处理用户请求",
"request_id", requestID,
)
}计算请求耗时
func TimingMiddleware() gin.HandlerFunc {
return func(ctx *gin.Context) {
ctx.Next()
// 获取开始时间并计算耗时
if startTime, exists := ctx.Get(xCtx.UserStartTimeKey.String()); exists {
elapsed := time.Since(startTime.(time.Time))
xLog.WithName(xLog.NamedMIDE).SugarInfo(ctx, "请求耗时",
"elapsed_ms", elapsed.Milliseconds(),
)
}
}
}传递到 Service 层
func GetUser(ctx *gin.Context) {
// ctx 已包含 RequestKey,可直接传递
user, err := userService.FindByID(ctx, id)
// ...
}func (s *UserService) FindByID(ctx context.Context, id string) (*entity.User, error) {
// 日志会自动提取 RequestKey 作为 Trace ID
xLog.WithName(xLog.NamedSERV).Info(ctx, "查询用户")
// GORM 操作也会继承 Trace ID
return s.repo.FindByID(ctx, id)
}