76 lines
1.7 KiB
Go
76 lines
1.7 KiB
Go
|
|
package middleware
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"bytes"
|
|||
|
|
"io"
|
|||
|
|
"strings"
|
|||
|
|
"time"
|
|||
|
|
|
|||
|
|
"gitea.com/bitwsd/document_ai/pkg/log"
|
|||
|
|
"github.com/gin-gonic/gin"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
const (
|
|||
|
|
maxBodySize = 1024 * 500 // 500KB 限制
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// 自定义 ResponseWriter 来捕获响应
|
|||
|
|
type bodyWriter struct {
|
|||
|
|
gin.ResponseWriter
|
|||
|
|
body *bytes.Buffer
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (w *bodyWriter) Write(b []byte) (int, error) {
|
|||
|
|
w.body.Write(b)
|
|||
|
|
return w.ResponseWriter.Write(b)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func AccessLog() gin.HandlerFunc {
|
|||
|
|
return func(c *gin.Context) {
|
|||
|
|
start := time.Now()
|
|||
|
|
path := c.Request.URL.Path
|
|||
|
|
raw := c.Request.URL.RawQuery
|
|||
|
|
|
|||
|
|
// 处理请求体
|
|||
|
|
var reqBody string
|
|||
|
|
if c.Request.Body != nil && (c.Request.Method == "POST" || c.Request.Method == "PUT") {
|
|||
|
|
// 读取并限制请求体大小
|
|||
|
|
bodyBytes, _ := io.ReadAll(io.LimitReader(c.Request.Body, maxBodySize))
|
|||
|
|
c.Request.Body = io.NopCloser(bytes.NewBuffer(bodyBytes)) // 重新设置 body
|
|||
|
|
reqBody = string(bodyBytes)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 设置自定义 ResponseWriter
|
|||
|
|
var responseBody string
|
|||
|
|
if !strings.Contains(c.GetHeader("Accept"), "text/event-stream") {
|
|||
|
|
bw := &bodyWriter{body: &bytes.Buffer{}, ResponseWriter: c.Writer}
|
|||
|
|
c.Writer = bw
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
c.Next()
|
|||
|
|
|
|||
|
|
// 获取响应体(非 SSE)
|
|||
|
|
if writer, ok := c.Writer.(*bodyWriter); ok {
|
|||
|
|
responseBody = writer.body.String()
|
|||
|
|
if len(responseBody) > maxBodySize {
|
|||
|
|
responseBody = responseBody[:maxBodySize] + "... (truncated)"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 记录访问日志
|
|||
|
|
log.Access(c.Request.Context(),
|
|||
|
|
"request_id", c.GetString("request_id"),
|
|||
|
|
"method", c.Request.Method,
|
|||
|
|
"path", path,
|
|||
|
|
"query", raw,
|
|||
|
|
"ip", c.ClientIP(),
|
|||
|
|
"user_agent", c.Request.UserAgent(),
|
|||
|
|
"status", c.Writer.Status(),
|
|||
|
|
"duration", time.Since(start),
|
|||
|
|
"request_body", reqBody,
|
|||
|
|
"response_body", responseBody,
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|