- 新增「简记memo」一体化小程序产品原型设计文档 - 新增简记memo完整版UI视觉设计规范和界面细节 - 添加IDEA项目配置文件.gitignore - 创建404页面HTML文件,包含响应式布局和错误提示 - 添加关于页面HTML文件,展示品牌介绍和团队信息 - 实现AES加解密工具函数,支持请求体加密 - 添加用户协议页面基础框架
89 lines
2.2 KiB
Go
89 lines
2.2 KiB
Go
// 请求日志中间件:记录请求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 生成请求ID(base36 紧凑字符串)
|
||
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),
|
||
)
|
||
}
|
||
}
|