diff --git a/controller/custom_oauth.go b/controller/custom_oauth.go index c21ec791..8172e297 100644 --- a/controller/custom_oauth.go +++ b/controller/custom_oauth.go @@ -501,7 +501,7 @@ func GetUserOAuthBindingsByAdmin(c *gin.Context) { } myRole := c.GetInt("role") - if myRole <= targetUser.Role && myRole != common.RoleRootUser { + if !canManageTargetRole(myRole, targetUser.Role) { common.ApiErrorMsg(c, "no permission") return } @@ -560,7 +560,7 @@ func UnbindCustomOAuthByAdmin(c *gin.Context) { } myRole := c.GetInt("role") - if myRole <= targetUser.Role && myRole != common.RoleRootUser { + if !canManageTargetRole(myRole, targetUser.Role) { common.ApiErrorMsg(c, "no permission") return } diff --git a/controller/passkey.go b/controller/passkey.go index 79930fdf..ac79e654 100644 --- a/controller/passkey.go +++ b/controller/passkey.go @@ -350,6 +350,11 @@ func AdminResetPasskey(c *gin.Context) { common.ApiError(c, err) return } + myRole := c.GetInt("role") + if !canManageTargetRole(myRole, user.Role) { + common.ApiErrorMsg(c, "no permission") + return + } if _, err := model.GetPasskeyByUserID(user.Id); err != nil { if errors.Is(err, model.ErrPasskeyNotFound) { diff --git a/controller/task_video.go b/controller/task_video.go index ce808df6..8be2e176 100644 --- a/controller/task_video.go +++ b/controller/task_video.go @@ -96,13 +96,13 @@ func updateVideoSingleTask(ctx context.Context, adaptor channel.TaskAdaptor, cha return fmt.Errorf("readAll failed for task %s: %w", taskId, err) } - logger.LogDebug(ctx, fmt.Sprintf("UpdateVideoSingleTask response: %s", string(responseBody))) + logger.LogDebug(ctx, "UpdateVideoSingleTask response: %s", responseBody) taskResult := &relaycommon.TaskInfo{} // try parse as New API response format var responseItems dto.TaskResponse[model.Task] if err = common.Unmarshal(responseBody, &responseItems); err == nil && responseItems.IsSuccess() { - logger.LogDebug(ctx, fmt.Sprintf("UpdateVideoSingleTask parsed as new api response format: %+v", responseItems)) + logger.LogDebug(ctx, "UpdateVideoSingleTask parsed as new api response format: %+v", responseItems) t := responseItems.Data taskResult.TaskID = t.TaskID taskResult.Status = string(t.Status) @@ -116,7 +116,7 @@ func updateVideoSingleTask(ctx context.Context, adaptor channel.TaskAdaptor, cha task.Data = redactVideoResponseBody(responseBody) } - logger.LogDebug(ctx, fmt.Sprintf("UpdateVideoSingleTask taskResult: %+v", taskResult)) + logger.LogDebug(ctx, "UpdateVideoSingleTask taskResult: %+v", taskResult) now := time.Now().Unix() if taskResult.Status == "" { diff --git a/controller/twofa.go b/controller/twofa.go index 123c74e2..ef86fd76 100644 --- a/controller/twofa.go +++ b/controller/twofa.go @@ -520,7 +520,7 @@ func AdminDisable2FA(c *gin.Context) { } myRole := c.GetInt("role") - if myRole <= targetUser.Role && myRole != common.RoleRootUser { + if !canManageTargetRole(myRole, targetUser.Role) { c.JSON(http.StatusOK, gin.H{ "success": false, "message": "无权操作同级或更高级用户的2FA设置", diff --git a/controller/user.go b/controller/user.go index 555ef9b3..dafb6609 100644 --- a/controller/user.go +++ b/controller/user.go @@ -264,6 +264,10 @@ func SearchUsers(c *gin.Context) { return } +func canManageTargetRole(myRole int, targetRole int) bool { + return myRole == common.RoleRootUser || myRole > targetRole +} + func GetUser(c *gin.Context) { id, err := strconv.Atoi(c.Param("id")) if err != nil { @@ -276,7 +280,7 @@ func GetUser(c *gin.Context) { return } myRole := c.GetInt("role") - if myRole <= user.Role && myRole != common.RoleRootUser { + if !canManageTargetRole(myRole, user.Role) { common.ApiErrorI18n(c, i18n.MsgUserNoPermissionSameLevel) return } @@ -567,11 +571,11 @@ func UpdateUser(c *gin.Context) { return } myRole := c.GetInt("role") - if myRole <= originUser.Role && myRole != common.RoleRootUser { + if !canManageTargetRole(myRole, originUser.Role) { common.ApiErrorI18n(c, i18n.MsgUserNoPermissionHigherLevel) return } - if myRole <= updatedUser.Role && myRole != common.RoleRootUser { + if !canManageTargetRole(myRole, updatedUser.Role) { common.ApiErrorI18n(c, i18n.MsgUserCannotCreateHigherLevel) return } @@ -610,7 +614,7 @@ func AdminClearUserBinding(c *gin.Context) { } myRole := c.GetInt("role") - if myRole <= user.Role && myRole != common.RoleRootUser { + if !canManageTargetRole(myRole, user.Role) { common.ApiErrorI18n(c, i18n.MsgUserNoPermissionSameLevel) return } @@ -872,7 +876,7 @@ func ManageUser(c *gin.Context) { return } myRole := c.GetInt("role") - if myRole <= user.Role && myRole != common.RoleRootUser { + if !canManageTargetRole(myRole, user.Role) { common.ApiErrorI18n(c, i18n.MsgUserNoPermissionHigherLevel) return } diff --git a/logger/logger.go b/logger/logger.go index 7b0c82de..867d8832 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -95,9 +95,11 @@ func LogDebug(ctx context.Context, msg string, args ...any) { } func logHelper(ctx context.Context, level string, msg string) { - id := ctx.Value(common.RequestIdKey) - if id == nil { - id = "SYSTEM" + var id any = "SYSTEM" + if ctx != nil { + if requestID := ctx.Value(common.RequestIdKey); requestID != nil { + id = requestID + } } now := time.Now() common.LogWriterMu.RLock() @@ -172,10 +174,13 @@ func FormatQuota(quota int) string { // LogJson 仅供测试使用 only for test func LogJson(ctx context.Context, msg string, obj any) { + if !common.DebugEnabled { + return + } jsonStr, err := common.Marshal(obj) if err != nil { LogError(ctx, fmt.Sprintf("json marshal failed: %s", err.Error())) return } - LogDebug(ctx, fmt.Sprintf("%s | %s", msg, string(jsonStr))) + LogDebug(ctx, "%s | %s", msg, jsonStr) } diff --git a/model/channel.go b/model/channel.go index 370a99bf..3e6d1866 100644 --- a/model/channel.go +++ b/model/channel.go @@ -12,6 +12,7 @@ import ( "github.com/QuantumNous/new-api/common" "github.com/QuantumNous/new-api/constant" "github.com/QuantumNous/new-api/dto" + "github.com/QuantumNous/new-api/logger" "github.com/QuantumNous/new-api/types" "github.com/samber/lo" @@ -250,10 +251,9 @@ func (channel *Channel) GetNextEnabledKey() (string, int, *types.NewAPIError) { if err != nil { return "", 0, types.NewError(err, types.ErrorCodeGetChannelFailed, types.ErrOptionWithSkipRetry()) } - //println("before polling index:", channel.ChannelInfo.MultiKeyPollingIndex) defer func() { if common.DebugEnabled { - println(fmt.Sprintf("channel %d polling index: %d", channel.Id, channel.ChannelInfo.MultiKeyPollingIndex)) + logger.LogDebug(nil, "channel %d polling index: %d", channel.Id, channel.ChannelInfo.MultiKeyPollingIndex) } if !common.MemoryCacheEnabled { _ = channel.SaveChannelInfo() diff --git a/model/channel_cache.go b/model/channel_cache.go index c9c50357..03740d2c 100644 --- a/model/channel_cache.go +++ b/model/channel_cache.go @@ -11,6 +11,7 @@ import ( "github.com/QuantumNous/new-api/common" "github.com/QuantumNous/new-api/constant" + "github.com/QuantumNous/new-api/logger" "github.com/QuantumNous/new-api/setting/ratio_setting" ) @@ -257,9 +258,12 @@ func CacheUpdateChannel(channel *Channel) { return } - println("CacheUpdateChannel:", channel.Id, channel.Name, channel.Status, channel.ChannelInfo.MultiKeyPollingIndex) - - println("before:", channelsIDM[channel.Id].ChannelInfo.MultiKeyPollingIndex) + if channelsIDM == nil { + channelsIDM = make(map[int]*Channel) + } + if oldChannel, ok := channelsIDM[channel.Id]; ok { + logger.LogDebug(nil, "CacheUpdateChannel before: id=%d, name=%s, status=%d, polling_index=%d", channel.Id, channel.Name, channel.Status, oldChannel.ChannelInfo.MultiKeyPollingIndex) + } channelsIDM[channel.Id] = channel - println("after :", channelsIDM[channel.Id].ChannelInfo.MultiKeyPollingIndex) + logger.LogDebug(nil, "CacheUpdateChannel after: id=%d, name=%s, status=%d, polling_index=%d", channel.Id, channel.Name, channel.Status, channel.ChannelInfo.MultiKeyPollingIndex) } diff --git a/model/user.go b/model/user.go index 5079acaf..8a650315 100644 --- a/model/user.go +++ b/model/user.go @@ -35,8 +35,8 @@ type User struct { OidcId string `json:"oidc_id" gorm:"column:oidc_id;index"` WeChatId string `json:"wechat_id" gorm:"column:wechat_id;index"` TelegramId string `json:"telegram_id" gorm:"column:telegram_id;index"` - VerificationCode string `json:"verification_code" gorm:"-:all"` // this field is only for Email verification, don't save it to database! - AccessToken *string `json:"access_token" gorm:"type:char(32);column:access_token;uniqueIndex"` // this token is for system management + VerificationCode string `json:"verification_code" gorm:"-:all"` // this field is only for Email verification, don't save it to database! + AccessToken *string `json:"-" gorm:"type:char(32);column:access_token;uniqueIndex"` // this token is for system management Quota int `json:"quota" gorm:"type:int;default:0"` UsedQuota int `json:"used_quota" gorm:"type:int;default:0;column:used_quota"` // used quota RequestCount int `json:"request_count" gorm:"type:int;default:0;"` // request number diff --git a/relay/channel/ali/image.go b/relay/channel/ali/image.go index 79bc2202..a391e40f 100644 --- a/relay/channel/ali/image.go +++ b/relay/channel/ali/image.go @@ -229,7 +229,7 @@ func asyncTaskWait(c *gin.Context, info *relaycommon.RelayInfo, taskID string) ( time.Sleep(time.Duration(5) * time.Second) for { - logger.LogDebug(c, fmt.Sprintf("asyncTaskWait step %d/%d, wait %d seconds", step, maxStep, waitSeconds)) + logger.LogDebug(c, "asyncTaskWait step %d/%d, wait %d seconds", step, maxStep, waitSeconds) step++ rsp, err, body := updateTask(info, taskID) responseBody = body @@ -320,11 +320,10 @@ func aliImageHandler(a *Adaptor, c *gin.Context, resp *http.Response, info *rela } } - //logger.LogDebug(c, "ali_async_task_result: "+string(originRespBody)) if a.IsSyncImageModel { - logger.LogDebug(c, "ali_sync_image_result: "+string(originRespBody)) + logger.LogDebug(c, "ali_sync_image_result: %s", originRespBody) } else { - logger.LogDebug(c, "ali_async_image_result: "+string(originRespBody)) + logger.LogDebug(c, "ali_async_image_result: %s", originRespBody) } imageResponses := responseAli2OpenAIImage(c, aliResponse, originRespBody, info, responseFormat) diff --git a/relay/channel/api_request.go b/relay/channel/api_request.go index ac7e2156..d5d953b3 100644 --- a/relay/channel/api_request.go +++ b/relay/channel/api_request.go @@ -292,9 +292,7 @@ func DoApiRequest(a Adaptor, c *gin.Context, info *common.RelayInfo, requestBody if err != nil { return nil, fmt.Errorf("get request url failed: %w", err) } - if common2.DebugEnabled { - println("fullRequestURL:", fullRequestURL) - } + logger.LogDebug(c, "fullRequestURL: %s", fullRequestURL) req, err := http.NewRequest(c.Request.Method, fullRequestURL, requestBody) if err != nil { return nil, fmt.Errorf("new request failed: %w", err) @@ -323,9 +321,7 @@ func DoFormRequest(a Adaptor, c *gin.Context, info *common.RelayInfo, requestBod if err != nil { return nil, fmt.Errorf("get request url failed: %w", err) } - if common2.DebugEnabled { - println("fullRequestURL:", fullRequestURL) - } + logger.LogDebug(c, "fullRequestURL: %s", fullRequestURL) req, err := http.NewRequest(c.Request.Method, fullRequestURL, requestBody) if err != nil { return nil, fmt.Errorf("new request failed: %w", err) @@ -388,13 +384,9 @@ func startPingKeepAlive(c *gin.Context, pingInterval time.Duration) context.Canc defer func() { // 增加panic恢复处理 if r := recover(); r != nil { - if common2.DebugEnabled { - println("SSE ping goroutine panic recovered:", fmt.Sprintf("%v", r)) - } - } - if common2.DebugEnabled { - println("SSE ping goroutine stopped.") + logger.LogDebug(c, "SSE ping goroutine panic recovered: %v", r) } + logger.LogDebug(c, "SSE ping goroutine stopped") }() if pingInterval <= 0 { @@ -405,15 +397,11 @@ func startPingKeepAlive(c *gin.Context, pingInterval time.Duration) context.Canc // 确保在任何情况下都清理ticker defer func() { ticker.Stop() - if common2.DebugEnabled { - println("SSE ping ticker stopped") - } + logger.LogDebug(c, "SSE ping ticker stopped") }() var pingMutex sync.Mutex - if common2.DebugEnabled { - println("SSE ping goroutine started") - } + logger.LogDebug(c, "SSE ping goroutine started") // 增加超时控制,防止goroutine长时间运行 maxPingDuration := 120 * time.Minute // 最大ping持续时间 @@ -425,9 +413,7 @@ func startPingKeepAlive(c *gin.Context, pingInterval time.Duration) context.Canc // 发送 ping 数据 case <-ticker.C: if err := sendPingData(c, &pingMutex); err != nil { - if common2.DebugEnabled { - println("SSE ping error, stopping goroutine:", err.Error()) - } + logger.LogDebug(c, "SSE ping error, stopping goroutine: %s", err.Error()) return } // 收到退出信号 @@ -438,9 +424,7 @@ func startPingKeepAlive(c *gin.Context, pingInterval time.Duration) context.Canc return // 超时保护,防止goroutine无限运行 case <-pingTimeout.C: - if common2.DebugEnabled { - println("SSE ping goroutine timeout, stopping") - } + logger.LogDebug(c, "SSE ping goroutine timeout, stopping") return } } @@ -463,9 +447,7 @@ func sendPingData(c *gin.Context, mutex *sync.Mutex) error { return } - if common2.DebugEnabled { - println("SSE ping data sent.") - } + logger.LogDebug(c, "SSE ping data sent") done <- nil }() @@ -507,9 +489,7 @@ func doRequest(c *gin.Context, req *http.Request, info *common.RelayInfo) (*http defer func() { if stopPinger != nil { stopPinger() - if common2.DebugEnabled { - println("SSE ping goroutine stopped by defer") - } + logger.LogDebug(c, "SSE ping goroutine stopped by defer") } }() } diff --git a/relay/channel/claude/relay-claude.go b/relay/channel/claude/relay-claude.go index e177e56d..046ccfe6 100644 --- a/relay/channel/claude/relay-claude.go +++ b/relay/channel/claude/relay-claude.go @@ -949,9 +949,7 @@ func ClaudeHandler(c *gin.Context, resp *http.Response, info *relaycommon.RelayI if err != nil { return nil, types.NewError(err, types.ErrorCodeBadResponseBody) } - if common.DebugEnabled { - println("responseBody: ", string(responseBody)) - } + logger.LogDebug(c, "responseBody: %s", responseBody) handleErr := HandleClaudeResponseData(c, info, claudeInfo, resp, responseBody) if handleErr != nil { return nil, handleErr diff --git a/relay/channel/gemini/relay-gemini-native.go b/relay/channel/gemini/relay-gemini-native.go index 1a434a43..5d91121c 100644 --- a/relay/channel/gemini/relay-gemini-native.go +++ b/relay/channel/gemini/relay-gemini-native.go @@ -26,9 +26,7 @@ func GeminiTextGenerationHandler(c *gin.Context, info *relaycommon.RelayInfo, re return nil, types.NewOpenAIError(err, types.ErrorCodeBadResponseBody, http.StatusInternalServerError) } - if common.DebugEnabled { - println(string(responseBody)) - } + logger.LogDebug(c, "Gemini native response body: %s", responseBody) // 解析为 Gemini 原生响应格式 var geminiResponse dto.GeminiChatResponse @@ -57,9 +55,7 @@ func NativeGeminiEmbeddingHandler(c *gin.Context, resp *http.Response, info *rel return nil, types.NewOpenAIError(err, types.ErrorCodeBadResponseBody, http.StatusInternalServerError) } - if common.DebugEnabled { - println(string(responseBody)) - } + logger.LogDebug(c, "Gemini native embedding response body: %s", responseBody) usage := service.ResponseText2Usage(c, "", info.UpstreamModelName, info.GetEstimatePromptTokens()) diff --git a/relay/channel/gemini/relay-gemini.go b/relay/channel/gemini/relay-gemini.go index 355c75d7..0824a0e1 100644 --- a/relay/channel/gemini/relay-gemini.go +++ b/relay/channel/gemini/relay-gemini.go @@ -1362,7 +1362,7 @@ func GeminiChatStreamHandler(c *gin.Context, info *relaycommon.RelayInfo, resp * } } - logger.LogDebug(c, fmt.Sprintf("info.SendResponseCount = %d", info.SendResponseCount)) + logger.LogDebug(c, "info.SendResponseCount = %d", info.SendResponseCount) if info.SendResponseCount == 0 { // send first response emptyResponse := helper.GenerateStartEmptyResponse(id, createAt, info.UpstreamModelName, nil) @@ -1422,9 +1422,7 @@ func GeminiChatHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.R return nil, types.NewOpenAIError(err, types.ErrorCodeBadResponseBody, http.StatusInternalServerError) } service.CloseResponseBodyGracefully(resp) - if common.DebugEnabled { - println(string(responseBody)) - } + logger.LogDebug(c, "Gemini response body: %s", responseBody) var geminiResponse dto.GeminiChatResponse err = common.Unmarshal(responseBody, &geminiResponse) if err != nil { diff --git a/relay/channel/openai/adaptor.go b/relay/channel/openai/adaptor.go index 6941ca54..581ae196 100644 --- a/relay/channel/openai/adaptor.go +++ b/relay/channel/openai/adaptor.go @@ -377,7 +377,7 @@ func (a *Adaptor) ConvertAudioRequest(c *gin.Context, info *relaycommon.RelayInf } // 打印类似 curl 命令格式的信息 - logger.LogDebug(c.Request.Context(), fmt.Sprintf("--form 'model=\"%s\"'", request.Model)) + logger.LogDebug(c.Request.Context(), "--form 'model=\"%s\"'", request.Model) // 遍历表单字段并打印输出 for key, values := range formData.Value { @@ -386,7 +386,7 @@ func (a *Adaptor) ConvertAudioRequest(c *gin.Context, info *relaycommon.RelayInf } for _, value := range values { writer.WriteField(key, value) - logger.LogDebug(c.Request.Context(), fmt.Sprintf("--form '%s=\"%s\"'", key, value)) + logger.LogDebug(c.Request.Context(), "--form '%s=\"%s\"'", key, value) } } @@ -398,8 +398,8 @@ func (a *Adaptor) ConvertAudioRequest(c *gin.Context, info *relaycommon.RelayInf // 使用 formData 中的第一个文件 fileHeader := fileHeaders[0] - logger.LogDebug(c.Request.Context(), fmt.Sprintf("--form 'file=@\"%s\"' (size: %d bytes, content-type: %s)", - fileHeader.Filename, fileHeader.Size, fileHeader.Header.Get("Content-Type"))) + logger.LogDebug(c.Request.Context(), "--form 'file=@\"%s\"' (size: %d bytes, content-type: %s)", + fileHeader.Filename, fileHeader.Size, fileHeader.Header.Get("Content-Type")) file, err := fileHeader.Open() if err != nil { @@ -418,7 +418,7 @@ func (a *Adaptor) ConvertAudioRequest(c *gin.Context, info *relaycommon.RelayInf // 关闭 multipart 编写器以设置分界线 writer.Close() c.Request.Header.Set("Content-Type", writer.FormDataContentType()) - logger.LogDebug(c.Request.Context(), fmt.Sprintf("--header 'Content-Type: %s'", writer.FormDataContentType())) + logger.LogDebug(c.Request.Context(), "--header 'Content-Type: %s'", writer.FormDataContentType()) return &requestBody, nil } } diff --git a/relay/channel/openai/relay-openai.go b/relay/channel/openai/relay-openai.go index a8575184..c21d4399 100644 --- a/relay/channel/openai/relay-openai.go +++ b/relay/channel/openai/relay-openai.go @@ -155,9 +155,9 @@ func OaiStreamHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Re containStreamUsage = true if common.DebugEnabled { - logger.LogDebug(c, fmt.Sprintf("Audio model usage extracted from second last SSE: PromptTokens=%d, CompletionTokens=%d, TotalTokens=%d, InputTokens=%d, OutputTokens=%d", + logger.LogDebug(c, "Audio model usage extracted from second last SSE: PromptTokens=%d, CompletionTokens=%d, TotalTokens=%d, InputTokens=%d, OutputTokens=%d", usage.PromptTokens, usage.CompletionTokens, usage.TotalTokens, - usage.InputTokens, usage.OutputTokens)) + usage.InputTokens, usage.OutputTokens) } } } @@ -200,9 +200,7 @@ func OpenaiHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Respo if err != nil { return nil, types.NewOpenAIError(err, types.ErrorCodeReadResponseBodyFailed, http.StatusInternalServerError) } - if common.DebugEnabled { - println("upstream response body:", string(responseBody)) - } + logger.LogDebug(c, "upstream response body: %s", responseBody) // Unmarshal to simpleResponse if info.ChannelType == constant.ChannelTypeOpenRouter && info.ChannelOtherSettings.IsOpenRouterEnterprise() { // 尝试解析为 openrouter enterprise diff --git a/relay/claude_handler.go b/relay/claude_handler.go index 54f8ced2..ec028c71 100644 --- a/relay/claude_handler.go +++ b/relay/claude_handler.go @@ -11,6 +11,7 @@ import ( "github.com/QuantumNous/new-api/common" "github.com/QuantumNous/new-api/constant" "github.com/QuantumNous/new-api/dto" + "github.com/QuantumNous/new-api/logger" relaycommon "github.com/QuantumNous/new-api/relay/common" "github.com/QuantumNous/new-api/relay/helper" "github.com/QuantumNous/new-api/service" @@ -177,9 +178,7 @@ func ClaudeHelper(c *gin.Context, info *relaycommon.RelayInfo) (newAPIError *typ } } - if common.DebugEnabled { - println("requestBody: ", string(jsonData)) - } + logger.LogDebug(c, "requestBody: %s", jsonData) requestBody = bytes.NewBuffer(jsonData) } @@ -202,7 +201,6 @@ func ClaudeHelper(c *gin.Context, info *relaycommon.RelayInfo) (newAPIError *typ } usage, newAPIError := adaptor.DoResponse(c, httpResp, info) - //log.Printf("usage: %v", usage) if newAPIError != nil { // reset status code 重置状态码 service.ResetStatusCode(newAPIError, statusCodeMappingStr) diff --git a/relay/common_handler/rerank.go b/relay/common_handler/rerank.go index f52a91b0..a3f30ae9 100644 --- a/relay/common_handler/rerank.go +++ b/relay/common_handler/rerank.go @@ -7,6 +7,7 @@ import ( "github.com/QuantumNous/new-api/common" "github.com/QuantumNous/new-api/constant" "github.com/QuantumNous/new-api/dto" + "github.com/QuantumNous/new-api/logger" "github.com/QuantumNous/new-api/relay/channel/xinference" relaycommon "github.com/QuantumNous/new-api/relay/common" "github.com/QuantumNous/new-api/service" @@ -21,9 +22,7 @@ func RerankHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Respo return nil, types.NewOpenAIError(err, types.ErrorCodeReadResponseBodyFailed, http.StatusInternalServerError) } service.CloseResponseBodyGracefully(resp) - if common.DebugEnabled { - println("reranker response body: ", string(responseBody)) - } + logger.LogDebug(c, "reranker response body: %s", responseBody) var jinaResp dto.RerankResponse if info.ChannelType == constant.ChannelTypeXinference { var xinRerankResponse xinference.XinRerankResponse diff --git a/relay/compatible_handler.go b/relay/compatible_handler.go index 7a5624eb..fdd54f39 100644 --- a/relay/compatible_handler.go +++ b/relay/compatible_handler.go @@ -102,7 +102,7 @@ func TextHelper(c *gin.Context, info *relaycommon.RelayInfo) (newAPIError *types } if common.DebugEnabled { if debugBytes, bErr := storage.Bytes(); bErr == nil { - println("requestBody: ", string(debugBytes)) + logger.LogDebug(c, "requestBody: %s", debugBytes) } } requestBody = common.ReaderOnly(storage) @@ -174,7 +174,7 @@ func TextHelper(c *gin.Context, info *relaycommon.RelayInfo) (newAPIError *types } } - logger.LogDebug(c, fmt.Sprintf("text request body: %s", string(jsonData))) + logger.LogDebug(c, "text request body: %s", jsonData) requestBody = bytes.NewBuffer(jsonData) } diff --git a/relay/embedding_handler.go b/relay/embedding_handler.go index b8e7fc9d..e2fda93e 100644 --- a/relay/embedding_handler.go +++ b/relay/embedding_handler.go @@ -58,7 +58,7 @@ func EmbeddingHelper(c *gin.Context, info *relaycommon.RelayInfo) (newAPIError * } } - logger.LogDebug(c, fmt.Sprintf("converted embedding request body: %s", string(jsonData))) + logger.LogDebug(c, "converted embedding request body: %s", jsonData) var requestBody io.Reader = bytes.NewBuffer(jsonData) statusCodeMappingStr := c.GetString("status_code_mapping") resp, err := adaptor.DoRequest(c, info, requestBody) diff --git a/relay/gemini_handler.go b/relay/gemini_handler.go index 3b4bafe2..df3bf47c 100644 --- a/relay/gemini_handler.go +++ b/relay/gemini_handler.go @@ -163,7 +163,7 @@ func GeminiHelper(c *gin.Context, info *relaycommon.RelayInfo) (newAPIError *typ } } - logger.LogDebug(c, "Gemini request body: "+string(jsonData)) + logger.LogDebug(c, "Gemini request body: %s", jsonData) requestBody = bytes.NewReader(jsonData) } @@ -262,7 +262,7 @@ func GeminiEmbeddingHandler(c *gin.Context, info *relaycommon.RelayInfo) (newAPI return newAPIErrorFromParamOverride(err) } } - logger.LogDebug(c, "Gemini embedding request body: "+string(jsonData)) + logger.LogDebug(c, "Gemini embedding request body: %s", jsonData) requestBody = bytes.NewReader(jsonData) resp, err := adaptor.DoRequest(c, info, requestBody) diff --git a/relay/helper/price.go b/relay/helper/price.go index 0e68edba..d1e16bca 100644 --- a/relay/helper/price.go +++ b/relay/helper/price.go @@ -45,7 +45,7 @@ func HandleGroupRatio(ctx *gin.Context, relayInfo *relaycommon.RelayInfo) types. // check auto group autoGroup, exists := ctx.Get("auto_group") if exists { - logger.LogDebug(ctx, fmt.Sprintf("final group: %s", autoGroup)) + logger.LogDebug(ctx, "final group: %s", autoGroup) relayInfo.UsingGroup = autoGroup.(string) } @@ -157,7 +157,7 @@ func ModelPriceHelper(c *gin.Context, info *relaycommon.RelayInfo, promptTokens } if common.DebugEnabled { - println(fmt.Sprintf("model_price_helper result: %s", priceData.ToSetting())) + logger.LogDebug(c, "model_price_helper result: %s", priceData.ToSetting()) } info.PriceData = priceData return priceData, nil @@ -299,9 +299,7 @@ func modelPriceHelperTiered(c *gin.Context, info *relaycommon.RelayInfo, promptT QuotaToPreConsume: preConsumedQuota, } - if common.DebugEnabled { - println(fmt.Sprintf("model_price_helper_tiered result: model=%s preConsume=%d quotaBeforeGroup=%.2f groupRatio=%.2f tier=%s", info.OriginModelName, preConsumedQuota, quotaBeforeGroup, groupRatioInfo.GroupRatio, trace.MatchedTier)) - } + logger.LogDebug(c, "model_price_helper_tiered result: model=%s preConsume=%d quotaBeforeGroup=%.2f groupRatio=%.2f tier=%s", info.OriginModelName, preConsumedQuota, quotaBeforeGroup, groupRatioInfo.GroupRatio, trace.MatchedTier) info.PriceData = priceData return priceData, nil diff --git a/relay/helper/stream_scanner.go b/relay/helper/stream_scanner.go index a9bc5e16..1d44b804 100644 --- a/relay/helper/stream_scanner.go +++ b/relay/helper/stream_scanner.go @@ -72,14 +72,11 @@ func StreamScannerHandler(c *gin.Context, resp *http.Response, info *relaycommon pingTicker = time.NewTicker(pingInterval) } - if common.DebugEnabled { - // print timeout and ping interval for debugging - println("relay timeout seconds:", common.RelayTimeout) - println("relay max idle conns:", common.RelayMaxIdleConns) - println("relay max idle conns per host:", common.RelayMaxIdleConnsPerHost) - println("streaming timeout seconds:", int64(streamingTimeout.Seconds())) - println("ping interval seconds:", int64(pingInterval.Seconds())) - } + logger.LogDebug(c, "relay timeout seconds: %d", common.RelayTimeout) + logger.LogDebug(c, "relay max idle conns: %d", common.RelayMaxIdleConns) + logger.LogDebug(c, "relay max idle conns per host: %d", common.RelayMaxIdleConnsPerHost) + logger.LogDebug(c, "streaming timeout seconds: %d", int64(streamingTimeout.Seconds())) + logger.LogDebug(c, "ping interval seconds: %d", int64(pingInterval.Seconds())) // 改进资源清理,确保所有 goroutine 正确退出 defer func() { @@ -127,9 +124,7 @@ func StreamScannerHandler(c *gin.Context, resp *http.Response, info *relaycommon info.StreamStatus.SetEndReason(relaycommon.StreamEndReasonPanic, fmt.Errorf("ping panic: %v", r)) common.SafeSendBool(stopChan, true) } - if common.DebugEnabled { - println("ping goroutine exited") - } + logger.LogDebug(c, "ping goroutine exited") }() // 添加超时保护,防止 goroutine 无限运行 @@ -155,9 +150,7 @@ func StreamScannerHandler(c *gin.Context, resp *http.Response, info *relaycommon info.StreamStatus.SetEndReason(relaycommon.StreamEndReasonPingFail, err) return } - if common.DebugEnabled { - println("ping data sent") - } + logger.LogDebug(c, "ping data sent") case <-time.After(10 * time.Second): logger.LogError(c, "ping data send timeout") info.StreamStatus.SetEndReason(relaycommon.StreamEndReasonPingFail, fmt.Errorf("ping send timeout")) @@ -217,9 +210,7 @@ func StreamScannerHandler(c *gin.Context, resp *http.Response, info *relaycommon info.StreamStatus.SetEndReason(relaycommon.StreamEndReasonPanic, fmt.Errorf("scanner panic: %v", r)) } common.SafeSendBool(stopChan, true) - if common.DebugEnabled { - println("scanner goroutine exited") - } + logger.LogDebug(c, "scanner goroutine exited") }() for scanner.Scan() { @@ -237,9 +228,7 @@ func StreamScannerHandler(c *gin.Context, resp *http.Response, info *relaycommon ticker.Reset(streamingTimeout) data := scanner.Text() - if common.DebugEnabled { - println(data) - } + logger.LogDebug(c, "stream scanner data: %s", data) if len(data) < 6 { continue @@ -265,9 +254,7 @@ func StreamScannerHandler(c *gin.Context, resp *http.Response, info *relaycommon } } else { info.StreamStatus.SetEndReason(relaycommon.StreamEndReasonDone, nil) - if common.DebugEnabled { - println("received [DONE], stopping scanner") - } + logger.LogDebug(c, "received [DONE], stopping scanner") return } } diff --git a/relay/image_handler.go b/relay/image_handler.go index e986dd89..7b3d961b 100644 --- a/relay/image_handler.go +++ b/relay/image_handler.go @@ -76,9 +76,7 @@ func ImageHelper(c *gin.Context, info *relaycommon.RelayInfo) (newAPIError *type } } - if common.DebugEnabled { - logger.LogDebug(c, fmt.Sprintf("image request body: %s", string(jsonData))) - } + logger.LogDebug(c, "image request body: %s", jsonData) requestBody = bytes.NewBuffer(jsonData) } } diff --git a/relay/mjproxy_handler.go b/relay/mjproxy_handler.go index ee48ca64..5b0750fe 100644 --- a/relay/mjproxy_handler.go +++ b/relay/mjproxy_handler.go @@ -14,6 +14,7 @@ import ( "github.com/QuantumNous/new-api/common" "github.com/QuantumNous/new-api/constant" "github.com/QuantumNous/new-api/dto" + "github.com/QuantumNous/new-api/logger" "github.com/QuantumNous/new-api/model" relaycommon "github.com/QuantumNous/new-api/relay/common" relayconstant "github.com/QuantumNous/new-api/relay/constant" @@ -473,7 +474,7 @@ func RelayMidjourneySubmit(c *gin.Context, relayInfo *relaycommon.RelayInfo) *dt c.Set("base_url", channel.GetBaseURL()) c.Set("channel_id", originTask.ChannelId) c.Request.Header.Set("Authorization", fmt.Sprintf("Bearer %s", channel.Key)) - log.Printf("检测到此操作为放大、变换、重绘,获取原channel信息: %s,%s", strconv.Itoa(originTask.ChannelId), channel.GetBaseURL()) + logger.LogDebug(c, "Midjourney action uses origin channel: id=%s, base_url=%s", strconv.Itoa(originTask.ChannelId), channel.GetBaseURL()) } midjRequest.Prompt = originTask.Prompt diff --git a/relay/rerank_handler.go b/relay/rerank_handler.go index 53cd6e47..edc69f68 100644 --- a/relay/rerank_handler.go +++ b/relay/rerank_handler.go @@ -8,6 +8,7 @@ import ( "github.com/QuantumNous/new-api/common" "github.com/QuantumNous/new-api/dto" + "github.com/QuantumNous/new-api/logger" relaycommon "github.com/QuantumNous/new-api/relay/common" "github.com/QuantumNous/new-api/relay/helper" "github.com/QuantumNous/new-api/service" @@ -67,9 +68,7 @@ func RerankHelper(c *gin.Context, info *relaycommon.RelayInfo) (newAPIError *typ } } - if common.DebugEnabled { - println(fmt.Sprintf("Rerank request body: %s", string(jsonData))) - } + logger.LogDebug(c, "Rerank request body: %s", jsonData) requestBody = bytes.NewBuffer(jsonData) } diff --git a/relay/responses_handler.go b/relay/responses_handler.go index 58324aa7..54ca3cbc 100644 --- a/relay/responses_handler.go +++ b/relay/responses_handler.go @@ -10,6 +10,7 @@ import ( "github.com/QuantumNous/new-api/common" appconstant "github.com/QuantumNous/new-api/constant" "github.com/QuantumNous/new-api/dto" + "github.com/QuantumNous/new-api/logger" relaycommon "github.com/QuantumNous/new-api/relay/common" relayconstant "github.com/QuantumNous/new-api/relay/constant" "github.com/QuantumNous/new-api/relay/helper" @@ -102,9 +103,7 @@ func ResponsesHelper(c *gin.Context, info *relaycommon.RelayInfo) (newAPIError * } } - if common.DebugEnabled { - println("requestBody: ", string(jsonData)) - } + logger.LogDebug(c, "requestBody: %s", jsonData) requestBody = bytes.NewBuffer(jsonData) } diff --git a/service/file_decoder.go b/service/file_decoder.go index 57898af7..27605a0f 100644 --- a/service/file_decoder.go +++ b/service/file_decoder.go @@ -85,7 +85,7 @@ func GetFileTypeFromUrl(c *gin.Context, url string, reason ...string) (string, e var readData []byte limits := []int{512, 8 * 1024, 24 * 1024, 64 * 1024} for _, limit := range limits { - logger.LogDebug(c, fmt.Sprintf("Trying to read %d bytes to determine file type", limit)) + logger.LogDebug(c, "Trying to read %d bytes to determine file type", limit) if len(readData) < limit { need := limit - len(readData) tmp := make([]byte, need) diff --git a/service/file_service.go b/service/file_service.go index bcf47442..03baf2de 100644 --- a/service/file_service.go +++ b/service/file_service.go @@ -50,7 +50,7 @@ func LoadFileSource(c *gin.Context, source types.FileSource, reason ...string) ( } if common.DebugEnabled { - logger.LogDebug(c, fmt.Sprintf("LoadFileSource starting for: %s", source.GetIdentifier())) + logger.LogDebug(c, "LoadFileSource starting for: %s", source.GetIdentifier()) } // 1. 快速检查内部缓存 @@ -208,7 +208,7 @@ func loadFromURL(c *gin.Context, url string, reason ...string) (*types.CachedFil } common.IncrementDiskFiles(base64Size) if common.DebugEnabled { - logger.LogDebug(c, fmt.Sprintf("File cached to disk: %s, size: %d bytes", diskPath, base64Size)) + logger.LogDebug(c, "File cached to disk: %s, size: %d bytes", diskPath, base64Size) } } } else { diff --git a/service/midjourney.go b/service/midjourney.go index bdb0fe50..c6397b7f 100644 --- a/service/midjourney.go +++ b/service/midjourney.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "io" - "log" "net/http" "strconv" "strings" @@ -13,6 +12,7 @@ import ( "github.com/QuantumNous/new-api/common" "github.com/QuantumNous/new-api/constant" "github.com/QuantumNous/new-api/dto" + "github.com/QuantumNous/new-api/logger" relayconstant "github.com/QuantumNous/new-api/relay/constant" "github.com/QuantumNous/new-api/setting" @@ -235,9 +235,8 @@ func DoMidjourneyHttpRequest(c *gin.Context, timeout time.Duration, fullRequestU return MidjourneyErrorWithStatusCodeWrapper(constant.MjErrorUnknown, "read_response_body_failed", statusCode), nullBytes, err } CloseResponseBodyGracefully(resp) - respStr := string(responseBody) - log.Printf("respStr: %s", respStr) - if respStr == "" { + logger.LogDebug(c, "midjourney response body: %s", responseBody) + if len(responseBody) == 0 { return MidjourneyErrorWithStatusCodeWrapper(constant.MjErrorUnknown, "empty_response_body", statusCode), responseBody, nil } else { err = json.Unmarshal(responseBody, &midjResponse) @@ -248,7 +247,6 @@ func DoMidjourneyHttpRequest(c *gin.Context, timeout time.Duration, fullRequestU } } } - //log.Printf("midjResponse: %v", midjResponse) //for k, v := range resp.Header { // c.Writer.Header().Set(k, v[0]) //} diff --git a/service/quota.go b/service/quota.go index e2ab25cf..862805d7 100644 --- a/service/quota.go +++ b/service/quota.go @@ -3,7 +3,6 @@ package service import ( "errors" "fmt" - "log" "math" "strings" "time" @@ -112,7 +111,7 @@ func PreWssConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, usag autoGroup, exists := common.GetContextKey(ctx, constant.ContextKeyAutoGroup) if exists { groupRatio = ratio_setting.GetGroupRatio(autoGroup.(string)) - log.Printf("final group ratio: %f", groupRatio) + logger.LogDebug(ctx, "final group ratio: %f", groupRatio) relayInfo.UsingGroup = autoGroup.(string) } diff --git a/service/task_polling.go b/service/task_polling.go index dc85e579..c5ec3ea3 100644 --- a/service/task_polling.go +++ b/service/task_polling.go @@ -372,7 +372,7 @@ func updateVideoSingleTask(ctx context.Context, adaptor TaskPollingAdaptor, ch * return fmt.Errorf("readAll failed for task %s: %w", taskId, err) } - logger.LogDebug(ctx, fmt.Sprintf("updateVideoSingleTask response: %s", string(responseBody))) + logger.LogDebug(ctx, "updateVideoSingleTask response: %s", responseBody) snap := task.Snapshot() @@ -380,7 +380,7 @@ func updateVideoSingleTask(ctx context.Context, adaptor TaskPollingAdaptor, ch * // try parse as New API response format var responseItems dto.TaskResponse[model.Task] if err = common.Unmarshal(responseBody, &responseItems); err == nil && responseItems.IsSuccess() { - logger.LogDebug(ctx, fmt.Sprintf("updateVideoSingleTask parsed as new api response format: %+v", responseItems)) + logger.LogDebug(ctx, "updateVideoSingleTask parsed as new api response format: %+v", responseItems) t := responseItems.Data taskResult.TaskID = t.TaskID taskResult.Status = string(t.Status) @@ -394,7 +394,7 @@ func updateVideoSingleTask(ctx context.Context, adaptor TaskPollingAdaptor, ch * task.Data = redactVideoResponseBody(responseBody) - logger.LogDebug(ctx, fmt.Sprintf("updateVideoSingleTask taskResult: %+v", taskResult)) + logger.LogDebug(ctx, "updateVideoSingleTask taskResult: %+v", taskResult) now := time.Now().Unix() if taskResult.Status == "" { @@ -488,7 +488,7 @@ func updateVideoSingleTask(ctx context.Context, adaptor TaskPollingAdaptor, ch * } } else { // No changes, skip update - logger.LogDebug(ctx, fmt.Sprintf("No update needed for task %s", task.TaskID)) + logger.LogDebug(ctx, "No update needed for task %s", task.TaskID) } if shouldSettle { diff --git a/service/token_counter.go b/service/token_counter.go index 63b76d97..933d9fd1 100644 --- a/service/token_counter.go +++ b/service/token_counter.go @@ -3,7 +3,6 @@ package service import ( "errors" "fmt" - "log" "math" "path/filepath" "strings" @@ -12,6 +11,7 @@ import ( "github.com/QuantumNous/new-api/common" "github.com/QuantumNous/new-api/constant" "github.com/QuantumNous/new-api/dto" + "github.com/QuantumNous/new-api/logger" relaycommon "github.com/QuantumNous/new-api/relay/common" constant2 "github.com/QuantumNous/new-api/relay/constant" "github.com/QuantumNous/new-api/types" @@ -111,7 +111,7 @@ func getImageToken(c *gin.Context, fileMeta *types.FileMeta, model string, strea width := config.Width height := config.Height - log.Printf("format: %s, width: %d, height: %d", format, width, height) + logger.LogDebug(c, "image token input: format=%s, width=%d, height=%d", format, width, height) if isPatchBased { // 32x32 patch-based calculation with 1536 cap and model multiplier @@ -171,9 +171,7 @@ func getImageToken(c *gin.Context, fileMeta *types.FileMeta, model string, strea tilesH := (finalH + 512 - 1) / 512 tiles := tilesW * tilesH - if common.DebugEnabled { - log.Printf("scaled to: %dx%d, tiles: %d", finalW, finalH, tiles) - } + logger.LogDebug(c, "image token scaled size: width=%d, height=%d, tiles=%d", finalW, finalH, tiles) return tiles*tileTokens + baseTokens, nil }