You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

85 lines
2.2 KiB

package middleware
import (
"bytes"
"io/ioutil"
"net/http"
"strconv"
"time"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/model/system"
"github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
"github.com/flipped-aurora/gin-vue-admin/server/service"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
var operationRecordService = service.ServiceGroupApp.SystemServiceGroup.OperationRecordService
func OperationRecord() gin.HandlerFunc {
return func(c *gin.Context) {
var body []byte
var userId int
if c.Request.Method != http.MethodGet {
var err error
body, err = ioutil.ReadAll(c.Request.Body)
if err != nil {
global.GVA_LOG.Error("read body from request error:", zap.Any("err", err))
} else {
c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(body))
}
}
if claims, ok := c.Get("claims"); ok {
waitUse := claims.(*request.CustomClaims)
userId = int(waitUse.ID)
} else {
id, err := strconv.Atoi(c.Request.Header.Get("x-user-id"))
if err != nil {
userId = 0
}
userId = id
}
record := system.SysOperationRecord{
Ip: c.ClientIP(),
Method: c.Request.Method,
Path: c.Request.URL.Path,
Agent: c.Request.UserAgent(),
Body: string(body),
UserID: userId,
}
// 存在某些未知错误 TODO
//values := c.Request.Header.Values("content-type")
//if len(values) >0 && strings.Contains(values[0], "boundary") {
// record.Body = "file"
//}
writer := responseBodyWriter{
ResponseWriter: c.Writer,
body: &bytes.Buffer{},
}
c.Writer = writer
now := time.Now()
c.Next()
latency := time.Now().Sub(now)
record.ErrorMessage = c.Errors.ByType(gin.ErrorTypePrivate).String()
record.Status = c.Writer.Status()
record.Latency = latency
record.Resp = writer.body.String()
if err := operationRecordService.CreateSysOperationRecord(record); err != nil {
global.GVA_LOG.Error("create operation record error:", zap.Any("err", err))
}
}
}
type responseBodyWriter struct {
gin.ResponseWriter
body *bytes.Buffer
}
func (r responseBodyWriter) Write(b []byte) (int, error) {
r.body.Write(b)
return r.ResponseWriter.Write(b)
}