refactor: 全面集成 slog 日志到 handler、service、middleware
- cmd/main.go: 集成 logger.Init 和日志中间件,替换标准 log 包 - handler 层: 5xx 错误记录完整日志,返回通用消息(防内部信息泄露) - service 层: LLM/图片生成/存储/认证等关键操作补充结构化日志 - auth 中间件: 记录认证失败原因 - generate.go: 后台管线任务使用带 task_id 的 logger
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/base64"
|
||||
"net/http"
|
||||
|
||||
"gen2d/internal/logger"
|
||||
"gen2d/internal/model"
|
||||
"gen2d/internal/service"
|
||||
|
||||
@@ -12,9 +13,9 @@ import (
|
||||
|
||||
// EditImageRequest 图片编辑请求。
|
||||
type EditImageRequest struct {
|
||||
Image string `json:"image" binding:"required"` // 底图 base64 编码
|
||||
Prompt string `json:"prompt" binding:"required"` // 编辑指令
|
||||
Count int `json:"count"` // 生成数量,默认 1
|
||||
Image string `json:"image" binding:"required"` // 底图 base64 编码
|
||||
Prompt string `json:"prompt" binding:"required"` // 编辑指令
|
||||
Count int `json:"count"` // 生成数量,默认 1
|
||||
}
|
||||
|
||||
// editAssetResponse 编辑结果素材(返回 base64)。
|
||||
@@ -38,7 +39,7 @@ func EditImage(c *gin.Context) {
|
||||
|
||||
imageData, err := base64.StdEncoding.DecodeString(req.Image)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, model.Fail(http.StatusBadRequest, "图片 base64 解码失败: "+err.Error()))
|
||||
c.JSON(http.StatusBadRequest, model.Fail(http.StatusBadRequest, "图片 base64 解码失败"))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -49,7 +50,8 @@ func EditImage(c *gin.Context) {
|
||||
|
||||
images, err := service.EditImages(c.Request.Context(), imageData, req.Prompt, count)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, model.Fail(http.StatusInternalServerError, "图片编辑失败: "+err.Error()))
|
||||
logger.FromCtx(c.Request.Context()).Error("图片编辑失败", "error", err)
|
||||
c.JSON(http.StatusInternalServerError, model.Fail(http.StatusInternalServerError, "图片编辑失败"))
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -3,11 +3,11 @@ package handler
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"gen2d/internal/logger"
|
||||
"gen2d/internal/model"
|
||||
"gen2d/internal/service"
|
||||
|
||||
@@ -55,8 +55,8 @@ type TaskResponse struct {
|
||||
|
||||
// AssetsResponse 素材列表响应。
|
||||
type AssetsResponse struct {
|
||||
Assets []AssetResponse `json:"assets"`
|
||||
Metadata service.AssetMetadata `json:"metadata"`
|
||||
Assets []AssetResponse `json:"assets"`
|
||||
Metadata service.AssetMetadata `json:"metadata"`
|
||||
}
|
||||
|
||||
// taskRecord 内存中的任务记录。
|
||||
@@ -103,11 +103,13 @@ func Generate(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, model.OK(GenerateResponse{TaskID: taskID}))
|
||||
|
||||
// 后台执行管线
|
||||
go runPipelineBg(projectID, taskID, req)
|
||||
go runPipelineBg(c.Request.Context(), projectID, taskID, req)
|
||||
}
|
||||
|
||||
// runPipelineBg 后台执行生成管线,更新任务状态。
|
||||
func runPipelineBg(projectID, taskID string, req GenerateRequest) {
|
||||
func runPipelineBg(ctx context.Context, projectID, taskID string, req GenerateRequest) {
|
||||
l := logger.With("task_id", taskID, "project_id", projectID)
|
||||
|
||||
updateStatus(taskID, "running", 10)
|
||||
|
||||
in := service.PipelineInput{
|
||||
@@ -129,11 +131,10 @@ func runPipelineBg(projectID, taskID string, req GenerateRequest) {
|
||||
},
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
output, err := service.RunPipeline(ctx, in)
|
||||
if err != nil {
|
||||
log.Printf("[generate] task %s failed: %v", taskID, err)
|
||||
updateFailed(taskID, err.Error())
|
||||
l.Error("task pipeline failed", "error", err)
|
||||
updateFailed(taskID, "生成管线执行失败")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -144,7 +145,8 @@ func runPipelineBg(projectID, taskID string, req GenerateRequest) {
|
||||
key := fmt.Sprintf("generation/%s/%s/%d.%s", projectID, taskID, i, a.Format)
|
||||
cdnURL, err := storageSvc.Upload(ctx, key, a.Data)
|
||||
if err != nil {
|
||||
updateFailed(taskID, "上传素材失败: "+err.Error())
|
||||
l.Error("upload asset failed", "index", i, "error", err)
|
||||
updateFailed(taskID, "上传素材失败")
|
||||
return
|
||||
}
|
||||
assets[i] = AssetResponse{
|
||||
@@ -168,7 +170,7 @@ func runPipelineBg(projectID, taskID string, req GenerateRequest) {
|
||||
metadata: output.Metadata,
|
||||
})
|
||||
|
||||
log.Printf("[generate] task %s completed, %d assets", taskID, len(assets))
|
||||
l.Info("task completed", "asset_count", len(assets))
|
||||
}
|
||||
|
||||
func updateStatus(taskID, status string, progress int) {
|
||||
|
||||
@@ -3,6 +3,7 @@ package handler
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"gen2d/internal/logger"
|
||||
"gen2d/internal/model"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -31,6 +32,7 @@ func Login(c *gin.Context) {
|
||||
|
||||
token, expiresIn, user, err := authSvc.Login(c.Request.Context(), req.Username, req.Password)
|
||||
if err != nil {
|
||||
logger.FromCtx(c.Request.Context()).Warn("登录失败", "username", req.Username, "error", err)
|
||||
c.JSON(http.StatusUnauthorized, model.Fail(http.StatusUnauthorized, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package handler
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"gen2d/internal/logger"
|
||||
"gen2d/internal/model"
|
||||
"gen2d/internal/service"
|
||||
|
||||
@@ -34,7 +35,8 @@ func PromptOptimize(c *gin.Context) {
|
||||
|
||||
output, err := service.RunPromptAgent(c.Request.Context(), in)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, model.Fail(http.StatusInternalServerError, "提示词优化失败: "+err.Error()))
|
||||
logger.FromCtx(c.Request.Context()).Error("提示词优化失败", "error", err)
|
||||
c.JSON(http.StatusInternalServerError, model.Fail(http.StatusInternalServerError, "提示词优化失败"))
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package handler
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"gen2d/internal/logger"
|
||||
"gen2d/internal/model"
|
||||
"gen2d/internal/service"
|
||||
|
||||
@@ -39,6 +40,7 @@ func Register(c *gin.Context) {
|
||||
|
||||
user, err := authSvc.Register(c.Request.Context(), req.Username, req.Password, req.Email)
|
||||
if err != nil {
|
||||
logger.FromCtx(c.Request.Context()).Warn("注册失败", "username", req.Username, "error", err)
|
||||
c.JSON(http.StatusConflict, model.Fail(http.StatusConflict, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package handler
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"gen2d/internal/logger"
|
||||
"gen2d/internal/model"
|
||||
"gen2d/internal/service"
|
||||
|
||||
@@ -27,6 +28,7 @@ func DownloadAsset(c *gin.Context) {
|
||||
|
||||
downloadURL, err := storageSvc.GetDownloadURL(c.Request.Context(), key)
|
||||
if err != nil {
|
||||
logger.FromCtx(c.Request.Context()).Error("生成下载链接失败", "key", key, "error", err)
|
||||
c.JSON(http.StatusInternalServerError, model.Fail(http.StatusInternalServerError, "生成下载链接失败"))
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user