diff --git a/backend/internal/handler/gateway_handler.go b/backend/internal/handler/gateway_handler.go index 284a4f8f..50097e0d 100644 --- a/backend/internal/handler/gateway_handler.go +++ b/backend/internal/handler/gateway_handler.go @@ -88,6 +88,9 @@ func (h *GatewayHandler) Messages(c *gin.Context) { return } + // 检查是否为 Claude Code 客户端,设置到 context 中 + SetClaudeCodeClientContext(c, body) + setOpsRequestContext(c, "", false, body) parsedReq, err := service.ParseGatewayRequest(body) @@ -286,8 +289,12 @@ func (h *GatewayHandler) Messages(c *gin.Context) { return } + // 捕获请求信息(用于异步记录,避免在 goroutine 中访问 gin.Context) + userAgent := c.GetHeader("User-Agent") + clientIP := c.ClientIP() + // 异步记录使用量(subscription已在函数开头获取) - go func(result *service.ForwardResult, usedAccount *service.Account) { + go func(result *service.ForwardResult, usedAccount *service.Account, ua, ip string) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() if err := h.gatewayService.RecordUsage(ctx, &service.RecordUsageInput{ @@ -296,10 +303,12 @@ func (h *GatewayHandler) Messages(c *gin.Context) { User: apiKey.User, Account: usedAccount, Subscription: subscription, + UserAgent: ua, + IPAddress: ip, }); err != nil { log.Printf("Record usage failed: %v", err) } - }(result, account) + }(result, account, userAgent, clientIP) return } } @@ -414,8 +423,12 @@ func (h *GatewayHandler) Messages(c *gin.Context) { return } + // 捕获请求信息(用于异步记录,避免在 goroutine 中访问 gin.Context) + userAgent := c.GetHeader("User-Agent") + clientIP := c.ClientIP() + // 异步记录使用量(subscription已在函数开头获取) - go func(result *service.ForwardResult, usedAccount *service.Account) { + go func(result *service.ForwardResult, usedAccount *service.Account, ua, ip string) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() if err := h.gatewayService.RecordUsage(ctx, &service.RecordUsageInput{ @@ -424,10 +437,12 @@ func (h *GatewayHandler) Messages(c *gin.Context) { User: apiKey.User, Account: usedAccount, Subscription: subscription, + UserAgent: ua, + IPAddress: ip, }); err != nil { log.Printf("Record usage failed: %v", err) } - }(result, account) + }(result, account, userAgent, clientIP) return } } diff --git a/backend/internal/handler/gemini_v1beta_handler.go b/backend/internal/handler/gemini_v1beta_handler.go index d639beb3..5c246456 100644 --- a/backend/internal/handler/gemini_v1beta_handler.go +++ b/backend/internal/handler/gemini_v1beta_handler.go @@ -314,8 +314,12 @@ func (h *GatewayHandler) GeminiV1BetaModels(c *gin.Context) { return } + // 捕获请求信息(用于异步记录,避免在 goroutine 中访问 gin.Context) + userAgent := c.GetHeader("User-Agent") + clientIP := c.ClientIP() + // 6) record usage async - go func(result *service.ForwardResult, usedAccount *service.Account) { + go func(result *service.ForwardResult, usedAccount *service.Account, ua, ip string) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() if err := h.gatewayService.RecordUsage(ctx, &service.RecordUsageInput{ @@ -324,10 +328,12 @@ func (h *GatewayHandler) GeminiV1BetaModels(c *gin.Context) { User: apiKey.User, Account: usedAccount, Subscription: subscription, + UserAgent: ua, + IPAddress: ip, }); err != nil { log.Printf("Record usage failed: %v", err) } - }(result, account) + }(result, account, userAgent, clientIP) return } } diff --git a/backend/internal/handler/openai_gateway_handler.go b/backend/internal/handler/openai_gateway_handler.go index 5f3474b0..8f6ef05f 100644 --- a/backend/internal/handler/openai_gateway_handler.go +++ b/backend/internal/handler/openai_gateway_handler.go @@ -263,8 +263,12 @@ func (h *OpenAIGatewayHandler) Responses(c *gin.Context) { return } + // 捕获请求信息(用于异步记录,避免在 goroutine 中访问 gin.Context) + userAgent := c.GetHeader("User-Agent") + clientIP := c.ClientIP() + // Async record usage - go func(result *service.OpenAIForwardResult, usedAccount *service.Account) { + go func(result *service.OpenAIForwardResult, usedAccount *service.Account, ua, ip string) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() if err := h.gatewayService.RecordUsage(ctx, &service.OpenAIRecordUsageInput{ @@ -273,10 +277,12 @@ func (h *OpenAIGatewayHandler) Responses(c *gin.Context) { User: apiKey.User, Account: usedAccount, Subscription: subscription, + UserAgent: ua, + IPAddress: ip, }); err != nil { log.Printf("Record usage failed: %v", err) } - }(result, account) + }(result, account, userAgent, clientIP) return } }