This commit is contained in:
2026-08-16 15:11:38 +08:00
parent f7f6db8695
commit a85477be80
40 changed files with 761 additions and 144 deletions
+24 -28
View File
@@ -8,6 +8,14 @@ import (
"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"
)
type captureWriter struct {
gin.ResponseWriter
body bytes.Buffer
@@ -17,7 +25,7 @@ type captureWriter struct {
func (w *captureWriter) Write(data []byte) (int, error) {
limit := w.maxBytes
if limit <= 0 {
limit = 32768
limit = 1024
}
if w.body.Len() < limit {
remaining := limit - w.body.Len()
@@ -30,44 +38,32 @@ func (w *captureWriter) Write(data []byte) (int, error) {
return w.ResponseWriter.Write(data)
}
func redactJSON(raw []byte) string {
return redactJSONLimit(raw, 32768)
}
func redactJSONLimit(raw []byte, limit int) string {
func redactJSON(raw []byte, contentType string, limit int) string {
if len(raw) == 0 {
return ""
}
if limit <= 0 {
limit = 32768
limit = 1024
}
if len(raw) > limit {
raw = raw[:limit]
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 {
return string(raw)
}
var clean func(any)
clean = func(current any) {
switch v := current.(type) {
case map[string]any:
for key, item := range v {
lower := strings.ToLower(key)
if strings.Contains(lower, "password") || strings.Contains(lower, "token") || strings.Contains(lower, "secret") {
v[key] = "******"
} else {
clean(item)
}
}
case []any:
for _, item := range v {
clean(item)
}
if len(text) > limit {
return "[超出记录长度]"
}
return text
}
clean(value)
maskOperationBody(value)
encoded, _ := json.Marshal(value)
if len(encoded) > limit {
return "[超出记录长度]"
}
return string(encoded)
}