Files
simple-memo/middleware/request_log.go
T
sunct 3c3bf53ae4 docs(website): 添加简记memo产品原型和UI设计规范文档
- 新增「简记memo」一体化小程序产品原型设计文档
- 新增简记memo完整版UI视觉设计规范和界面细节
- 添加IDEA项目配置文件.gitignore
- 创建404页面HTML文件,包含响应式布局和错误提示
- 添加关于页面HTML文件,展示品牌介绍和团队信息
- 实现AES加解密工具函数,支持请求体加密
- 添加用户协议页面基础框架
2026-07-31 14:12:32 +08:00

89 lines
2.2 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.
// 请求日志中间件:记录请求ID、路由、客户端IP等关键信息
package middleware
import (
"context"
"fmt"
"simple-memo/global"
"simple-memo/utils"
"strconv"
"time"
"github.com/gin-gonic/gin"
"github.com/sony/sonyflake"
"go.uber.org/zap"
)
// requestIDSF 用于生成全局唯一的请求ID
var requestIDSF *sonyflake.Sonyflake
func init() {
requestIDSF = sonyflake.NewSonyflake(sonyflake.Settings{})
}
// genRequestID 基于 sonyflake 生成请求IDbase36 紧凑字符串)
func genRequestID() string {
if requestIDSF == nil {
return fmt.Sprintf("%x", time.Now().UnixNano())
}
id, err := requestIDSF.NextID()
if err != nil {
return fmt.Sprintf("%x", time.Now().UnixNano())
}
// base36 编码:紧凑且只含 [0-9a-z]
return strconv.FormatUint(id, 36)
}
// RequestLog 请求日志中间件
func RequestLog() gin.HandlerFunc {
return func(c *gin.Context) {
start := time.Now()
// 优先从请求头获取 request-id,否则自动生成
requestID := c.GetHeader("X-Request-ID")
if requestID == "" {
requestID = genRequestID()
}
// 客户端IP
clientIP := c.ClientIP()
// 路由路径
route := c.Request.URL.Path
// 请求方法
method := c.Request.Method
// 写入标准 context,供整条链路使用
ctx := context.WithValue(c.Request.Context(), utils.RequestIdKey, requestID)
ctx = context.WithValue(ctx, utils.RequestRouteKey, route)
ctx = context.WithValue(ctx, utils.ClientIPKey, clientIP)
c.Request = c.Request.WithContext(ctx)
// 同时记录到 gin context,兼容老代码
c.Set("request_id", requestID)
c.Set("client_ip", clientIP)
c.Set("route", route)
// 打印请求进入日志
global.Logger.Info("【请求进入】",
zap.String("request_id", requestID),
zap.String("route", route),
zap.String("method", method),
zap.String("client_ip", clientIP),
zap.String("user_agent", c.Request.UserAgent()),
)
c.Next()
// 请求结束后打印耗时日志
duration := time.Since(start)
global.Logger.Info("【请求结束】",
zap.String("request_id", requestID),
zap.String("route", route),
zap.Int("status", c.Writer.Status()),
zap.Duration("duration", duration),
)
}
}