package middleware import ( "bytes" "gitee.ltd/lxh/logger/log" "github.com/gin-gonic/gin" jsoniter "github.com/json-iterator/go" "io" "regexp" "strings" "time" "wireguard-dashboard/model/entity" "wireguard-dashboard/repository" ) // bodyWriter // @description: 重写ResponseBody type bodyWriter struct { gin.ResponseWriter body *bytes.Buffer } func SystemLogRequest() gin.HandlerFunc { return func(c *gin.Context) { var userId string if userInfo, ok := c.Get("user"); ok { userId = userInfo.(*entity.User).Id } // 开始时间 start := time.Now() host := c.Request.Host // 请求域名 path := c.Request.URL.Path // 接口地址 query := c.Request.URL.RawQuery // 参数 if strings.Contains(path, "/api/dashboard/list") { c.Next() return } var bodyStr string if !strings.Contains(path, "/api/login") { body, err := c.GetRawData() // body参数 if err == nil { bodyStr = string(body) c.Request.Body = io.NopCloser(bytes.NewBuffer(body)) reg := regexp.MustCompile("\\s+") bodyStr = reg.ReplaceAllString(bodyStr, "") } } method := c.Request.Method // 请求方式 ip := c.ClientIP() // 取出IP // 处理实际客户端IP if c.Request.Header.Get("U-Real-Ip") != "" { ip = c.Request.Header.Get("U-Real-Ip") // 这个是网关Nginx自定义的Header头 } else if c.Request.Header.Get("U-Forwarded-For") != "" { ip = c.Request.Header.Get("U-Forwarded-For") // 这个是网关Nginx自定义的Header头 } ua := c.Request.UserAgent() // UA // 重写客户端IP c.Request.Header.Set("X-Forwarded-For", ip) c.Request.Header.Set("X-Real-Ip", ip) // 拦截response bw := &bodyWriter{body: bytes.NewBufferString(""), ResponseWriter: c.Writer} c.Writer = bw header := c.Request.Header headerStr, _ := jsoniter.MarshalToString(header) // 执行下一步请求 c.Next() // 计算耗时 cost := time.Since(start).Milliseconds() // 组装实体 l := entity.SystemLog{ UserId: userId, ClientIP: ip, Host: host, Method: method, Uri: path, Header: headerStr, Body: bodyStr, Form: "", Query: query, UserAgent: ua, Cost: cost, StatusCode: c.Writer.Status(), Response: "", } // 如果不是返回200,把返回值保存一下 if c.Writer.Status() != 200 { resp := bw.body.String() l.Response = resp } go func() { if er := repository.SystemLog().SaveLog(&l); er != nil { log.Debugf("请求日志: %+v", l) log.Errorf("保存请求日志失败: %v", er) } }() } }