79 lines
1.7 KiB
Go
79 lines
1.7 KiB
Go
package middleware
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"strings"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// The global access logger is the single request/response capture point.
|
|
// OperationAudit consumes these values after the handler returns, avoiding a
|
|
// second body read/writer wrapper.
|
|
const (
|
|
ctxReqBodyKey = "kra_req_body"
|
|
ctxRespBufferKey = "kra_resp_buffer"
|
|
ctxRespTruncatedKey = "kra_resp_truncated"
|
|
ctxRespTextKey = "kra_resp_text"
|
|
)
|
|
|
|
type captureWriter struct {
|
|
gin.ResponseWriter
|
|
body bytes.Buffer
|
|
maxBytes int
|
|
truncated bool
|
|
}
|
|
|
|
func (w *captureWriter) Write(data []byte) (int, error) {
|
|
limit := w.maxBytes
|
|
if limit <= 0 {
|
|
limit = 1024
|
|
}
|
|
if w.body.Len() < limit {
|
|
remaining := limit - w.body.Len()
|
|
if len(data) > remaining {
|
|
_, _ = w.body.Write(data[:remaining])
|
|
w.truncated = true
|
|
} else {
|
|
_, _ = w.body.Write(data)
|
|
}
|
|
} else if len(data) > 0 {
|
|
w.truncated = true
|
|
}
|
|
return w.ResponseWriter.Write(data)
|
|
}
|
|
|
|
func (w *captureWriter) Truncated() bool { return w != nil && w.truncated }
|
|
|
|
func redactJSON(raw []byte, contentType string, limit int) string {
|
|
if len(raw) == 0 {
|
|
return ""
|
|
}
|
|
if limit <= 0 {
|
|
limit = 1024
|
|
}
|
|
text := string(raw)
|
|
if !strings.Contains(strings.ToLower(contentType), "json") {
|
|
if len(text) > limit {
|
|
return "[超出记录长度]"
|
|
}
|
|
return text
|
|
}
|
|
var value any
|
|
if json.Unmarshal(raw, &value) != nil {
|
|
if len(text) > limit {
|
|
return "[超出记录长度]"
|
|
}
|
|
return text
|
|
}
|
|
maskOperationBody(value)
|
|
encoded, _ := json.Marshal(value)
|
|
if len(encoded) > limit {
|
|
return "[超出记录长度]"
|
|
}
|
|
return string(encoded)
|
|
}
|
|
|
|
func stringValue(value any) string { text, _ := value.(string); return text }
|