Files
junhong_cmp_fiber/pkg/logger/middleware.go
huang cb75b5668b
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m10s
操作日志
2026-04-27 12:16:38 +08:00

100 lines
2.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package logger
import (
"context"
"time"
"github.com/break/junhong_cmp_fiber/pkg/constants"
"github.com/gofiber/fiber/v2"
"go.uber.org/zap"
)
const (
// MaxBodyLogSize 限制记录的请求/响应 body 大小为 50KB
MaxBodyLogSize = 50 * 1024
)
// truncateBody 截断 body 到指定大小
func truncateBody(body []byte, maxSize int) string {
if len(body) == 0 {
return ""
}
if len(body) <= maxSize {
return string(body)
}
// 超过限制,截断并添加提示
return string(body[:maxSize]) + "... (truncated)"
}
// Middleware 创建 Fiber 日志中间件
// 记录所有 HTTP 请求到访问日志(包括请求和响应 body
func Middleware() fiber.Handler {
return func(c *fiber.Ctx) error {
// 记录请求开始时间
startTime := time.Now()
c.Locals(constants.ContextKeyStartTime, startTime)
// 注入请求上下文,供 Service 层审计日志复用
ctx := c.UserContext()
if rid := c.Locals(constants.ContextKeyRequestID); rid != nil {
if requestID, ok := rid.(string); ok && requestID != "" {
ctx = context.WithValue(ctx, constants.ContextKeyRequestID, requestID)
}
}
ctx = context.WithValue(ctx, constants.ContextKeyIP, c.IP())
ctx = context.WithValue(ctx, constants.ContextKeyUserAgent, c.Get("User-Agent"))
ctx = context.WithValue(ctx, constants.ContextKeyRequestPath, c.Path())
ctx = context.WithValue(ctx, constants.ContextKeyRequestMethod, c.Method())
c.SetUserContext(ctx)
// 获取请求 body在 c.Next() 之前读取)
requestBody := truncateBody(c.Body(), MaxBodyLogSize)
// 获取 query 参数
queryParams := string(c.Request().URI().QueryString())
// 处理请求
err := c.Next()
// 计算请求持续时间
duration := time.Since(startTime)
// 获取请求 ID由 requestid 中间件设置)
requestID := ""
if rid := c.Locals(constants.ContextKeyRequestID); rid != nil {
requestID = rid.(string)
}
// 获取用户 ID由 auth 中间件设置)
var userID uint
if uid := c.Locals(constants.ContextKeyUserID); uid != nil {
if id, ok := uid.(uint); ok {
userID = id
}
}
// 获取响应 body
responseBody := truncateBody(c.Response().Body(), MaxBodyLogSize)
// 记录访问日志
accessLogger := GetAccessLogger()
accessLogger.Info("",
zap.String("method", c.Method()),
zap.String("path", c.Path()),
zap.String("query", queryParams),
zap.Int("status", c.Response().StatusCode()),
zap.Float64("duration_ms", float64(duration.Microseconds())/1000.0),
zap.String("request_id", requestID),
zap.String("ip", c.IP()),
zap.String("user_agent", c.Get("User-Agent")),
zap.Uint("user_id", userID),
zap.String("request_body", requestBody),
zap.String("response_body", responseBody),
)
return err
}
}