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:
2026-05-25 14:31:04 +08:00
parent 681bc8f472
commit 25c11ed649
13 changed files with 159 additions and 39 deletions
+50 -6
View File
@@ -11,13 +11,13 @@ import (
"image/color"
"image/png"
"io"
"log"
"mime/multipart"
"net/http"
"strings"
"time"
"gen2d/internal/config"
"gen2d/internal/logger"
)
// imgCfg 保存文生图配置,由 main 通过 InitImageGenConfig 注入。
@@ -64,21 +64,33 @@ func GenerateImages(ctx context.Context, prompt string, params AssetParams) ([]G
count = params.Frames.Directions * params.Frames.FramesPerDirection
}
l := logger.FromCtx(ctx)
if imgCfg.APIKey != "" {
width, height := imgCfg.Width, imgCfg.Height
if params.Resolution > 0 {
width = params.Resolution
height = params.Resolution
}
log.Println("[inference] calling image gen API")
return callImageAPI(ctx, prompt, count, width, height)
l.Info("calling image gen API",
"model", imgCfg.Model,
"count", count,
"size", fmt.Sprintf("%dx%d", width, height),
)
images, err := callImageAPI(ctx, prompt, count, width, height)
if err != nil {
l.Error("image gen API failed", "error", err)
return nil, err
}
l.Info("image gen API succeeded", "image_count", len(images))
return images, nil
}
size := params.Resolution
if size <= 0 {
size = 64
}
log.Println("[inference] image API key not configured, using mock")
l.Warn("image API key not configured, using mock")
return generateMockImages(size, count)
}
@@ -107,10 +119,15 @@ func callImageAPI(ctx context.Context, prompt string, count, width, height int)
retryDelay = 5 * time.Second
}
l := logger.FromCtx(ctx)
var lastErr error
for attempt := 0; attempt <= maxRetries; attempt++ {
if attempt > 0 {
log.Printf("[inference] retrying image API (attempt %d/%d)", attempt, maxRetries)
l.Warn("retrying image API",
"attempt", attempt,
"max_retries", maxRetries,
)
select {
case <-ctx.Done():
return nil, fmt.Errorf("context cancelled during retry: %w", ctx.Err())
@@ -128,6 +145,7 @@ func callImageAPI(ctx context.Context, prompt string, count, width, height int)
resp, err := imageHTTPClient.Do(req)
if err != nil {
lastErr = fmt.Errorf("send request: %w", err)
l.Warn("image API request failed", "error", lastErr)
continue
}
@@ -140,8 +158,18 @@ func callImageAPI(ctx context.Context, prompt string, count, width, height int)
if resp.StatusCode >= 500 {
lastErr = fmt.Errorf("image api error %d: %s", resp.StatusCode, string(b))
l.Error("image API server error",
"status", resp.StatusCode,
"body", string(b),
"attempt", attempt,
)
continue
}
// 4xx 不重试
l.Error("image API client error",
"status", resp.StatusCode,
"body", string(b),
)
return nil, fmt.Errorf("image api error %d: %s", resp.StatusCode, string(b))
}
@@ -205,10 +233,17 @@ func downloadImage(ctx context.Context, url string) ([]byte, error) {
// EditImages 图片编辑接口,调用 OpenAI 兼容 Images Edits API(multipart/form-data)。
func EditImages(ctx context.Context, imageData []byte, prompt string, count int) ([]GeneratedImage, error) {
l := logger.FromCtx(ctx)
if imgCfg.APIKey == "" {
return nil, fmt.Errorf("image API key not configured")
}
l.Info("calling image edit API",
"model", imgCfg.Model,
"count", count,
)
var buf bytes.Buffer
writer := multipart.NewWriter(&buf)
@@ -239,16 +274,25 @@ func EditImages(ctx context.Context, imageData []byte, prompt string, count int)
resp, err := imageHTTPClient.Do(req)
if err != nil {
l.Error("image edit API request failed", "error", err)
return nil, fmt.Errorf("send request: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
b, _ := io.ReadAll(io.LimitReader(resp.Body, 4096))
l.Error("image edit API error", "status", resp.StatusCode, "body", string(b))
return nil, fmt.Errorf("image edit api error %d: %s", resp.StatusCode, string(b))
}
return parseImageResponse(ctx, resp.Body, imgCfg.Width, imgCfg.Height)
images, err := parseImageResponse(ctx, resp.Body, imgCfg.Width, imgCfg.Height)
if err != nil {
l.Error("image edit response parse failed", "error", err)
return nil, err
}
l.Info("image edit API succeeded", "image_count", len(images))
return images, nil
}
// ======================== 质检 ========================