package middleware import ( "time" "github.com/gin-gonic/gin" "go.uber.org/zap" "go.uber.org/zap/zapcore" ) // GinLoggerMiddleware Gin日志中间件 func GinLoggerMiddleware() gin.HandlerFunc { return func(c *gin.Context) { // 记录请求开始时间 start := time.Now() // 记录请求路径 path := c.Request.URL.Path // 记录查询参数 query := c.Request.URL.RawQuery // 处理请求 c.Next() // 计算请求处理耗时 latency := time.Since(start) // 获取响应状态码 status := c.Writer.Status() // 获取客户端IP clientIP := c.ClientIP() // 获取请求方法 method := c.Request.Method // 获取用户代理 userAgent := c.Request.UserAgent() // 获取响应体大小 bodySize := c.Writer.Size() // 获取错误信息(如果有) var errorMsg string if len(c.Errors) > 0 { errorMsg = c.Errors.String() } // 构建日志字段 fields := []zapcore.Field{ zap.Int("status", status), // 响应状态码 zap.String("method", method), // 请求方法 zap.String("path", path), // 请求路径 zap.String("query", query), // 查询参数 zap.String("ip", clientIP), // 客户端IP zap.String("user-agent", userAgent), // 用户代理 zap.Duration("latency", latency), // 处理耗时 zap.Int("body_size", bodySize), // 响应体大小 zap.String("time", time.Now().Format("2006-01-02 15:04:05")), // 请求时间 } // 如果存在错误,添加错误信息字段 if errorMsg != "" { fields = append(fields, zap.String("error", errorMsg)) } // 根据状态码级别记录日志 switch { case status >= 500: // 服务器错误(5xx):使用Error级别 zap.L().Error("服务器错误", fields...) case status >= 400: // 客户端错误(4xx):使用Warn级别 zap.L().Warn("客户端错误", fields...) default: // 成功请求(2xx/3xx):使用Info级别 zap.L().Info("请求完成", fields...) } } } // GinRecoveryMiddleware Gin恢复中间件(捕获panic) func GinRecoveryMiddleware() gin.HandlerFunc { return func(c *gin.Context) { defer func() { if err := recover(); err != nil { // 获取客户端IP clientIP := c.ClientIP() // 获取请求信息 path := c.Request.URL.Path method := c.Request.Method // 记录panic详细信息 zap.L().Error("请求发生panic", zap.Any("error", err), // panic错误 zap.String("method", method), // 请求方法 zap.String("path", path), // 请求路径 zap.String("ip", clientIP), // 客户端IP zap.String("stack", string(zap.Stack("").String)), // 堆栈信息 ) // 返回500错误响应 c.AbortWithStatusJSON(500, gin.H{ "code": 500, "message": "服务器内部错误", }) } }() c.Next() } }