wireguard-dashboard/middleware/system_log.go
2024-06-03 17:09:45 +08:00

108 lines
2.6 KiB
Go
Raw Permalink 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.

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)
}
}()
}
}