添加请求追踪中间件以记录请求和响应内容 在用户订阅查询中新增includeExpired参数支持查询历史记录 完善配置系统以支持float64类型默认值解析
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
@@ -18,6 +20,17 @@ import (
|
||||
"github.com/perfect-panel/server/pkg/trace"
|
||||
)
|
||||
|
||||
// bodyLogWriter is a wrapper for gin.ResponseWriter to capture response body
|
||||
type bodyLogWriter struct {
|
||||
gin.ResponseWriter
|
||||
body *bytes.Buffer
|
||||
}
|
||||
|
||||
func (w bodyLogWriter) Write(b []byte) (int, error) {
|
||||
w.body.Write(b)
|
||||
return w.ResponseWriter.Write(b)
|
||||
}
|
||||
|
||||
// statusByWriter returns a span status code and message for an HTTP status code
|
||||
// value returned by a server. Status codes in the 400-499 range are not
|
||||
// returned as errors.
|
||||
@@ -59,6 +72,13 @@ func TraceMiddleware(_ *svc.ServiceContext) func(ctx *gin.Context) {
|
||||
ctx := c.Request.Context()
|
||||
tracer := trace.TracerFromContext(ctx)
|
||||
|
||||
// Capture Request Body
|
||||
var reqBody []byte
|
||||
if c.Request.Body != nil {
|
||||
reqBody, _ = io.ReadAll(c.Request.Body)
|
||||
c.Request.Body = io.NopCloser(bytes.NewBuffer(reqBody)) // Restore body
|
||||
}
|
||||
|
||||
spanName := c.FullPath()
|
||||
method := c.Request.Method
|
||||
|
||||
@@ -78,13 +98,39 @@ func TraceMiddleware(_ *svc.ServiceContext) func(ctx *gin.Context) {
|
||||
attribute.String("http.request_id", requestId),
|
||||
semconv.HTTPRouteKey.String(c.FullPath()),
|
||||
)
|
||||
|
||||
// Record Request Body (limit to 1MB)
|
||||
if len(reqBody) > 0 {
|
||||
limit := 1048576
|
||||
if len(reqBody) > limit {
|
||||
span.SetAttributes(attribute.String("http.request.body", string(reqBody[:limit])+"...(truncated)"))
|
||||
} else {
|
||||
span.SetAttributes(attribute.String("http.request.body", string(reqBody)))
|
||||
}
|
||||
}
|
||||
|
||||
// context with request host
|
||||
ctx = context.WithValue(ctx, constant.CtxKeyRequestHost, c.Request.Host)
|
||||
// restructure context
|
||||
c.Request = c.Request.WithContext(ctx)
|
||||
|
||||
// Wrap ResponseWriter to capture Response Body
|
||||
blw := &bodyLogWriter{body: bytes.NewBufferString(""), ResponseWriter: c.Writer}
|
||||
c.Writer = blw
|
||||
|
||||
c.Next()
|
||||
|
||||
// Record Response Body (limit to 1MB)
|
||||
respBody := blw.body.String()
|
||||
if len(respBody) > 0 {
|
||||
limit := 1048576
|
||||
if len(respBody) > limit {
|
||||
span.SetAttributes(attribute.String("http.response.body", respBody[:limit]+"...(truncated)"))
|
||||
} else {
|
||||
span.SetAttributes(attribute.String("http.response.body", respBody))
|
||||
}
|
||||
}
|
||||
|
||||
// handle response related attributes
|
||||
status := c.Writer.Status()
|
||||
span.SetStatus(statusByWriter(status))
|
||||
@@ -97,7 +143,5 @@ func TraceMiddleware(_ *svc.ServiceContext) func(ctx *gin.Context) {
|
||||
span.RecordError(err.Err)
|
||||
}
|
||||
}
|
||||
|
||||
span.SetAttributes(semconv.HTTPResponseBodySizeKey.Int(c.Writer.Size()))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user