mirror of
https://github.com/zeromicro/go-zero.git
synced 2026-05-07 15:10:01 +08:00
fix: large memory usage on detail logging post requests (#5039)
This commit is contained in:
@@ -24,8 +24,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
limitBodyBytes = 1024
|
limitBodyBytes = 1024
|
||||||
defaultSlowThreshold = time.Millisecond * 500
|
limitDetailedBodyBytes = 4096
|
||||||
|
defaultSlowThreshold = time.Millisecond * 500
|
||||||
)
|
)
|
||||||
|
|
||||||
var slowThreshold = syncx.ForAtomicDuration(defaultSlowThreshold)
|
var slowThreshold = syncx.ForAtomicDuration(defaultSlowThreshold)
|
||||||
@@ -94,7 +95,8 @@ func DetailedLogHandler(next http.Handler) http.Handler {
|
|||||||
lrw := newDetailLoggedResponseWriter(rw, &buf)
|
lrw := newDetailLoggedResponseWriter(rw, &buf)
|
||||||
|
|
||||||
var dup io.ReadCloser
|
var dup io.ReadCloser
|
||||||
r.Body, dup = iox.DupReadCloser(r.Body)
|
// https://github.com/zeromicro/go-zero/issues/3564
|
||||||
|
r.Body, dup = iox.LimitDupReadCloser(r.Body, limitDetailedBodyBytes)
|
||||||
logs := new(internal.LogCollector)
|
logs := new(internal.LogCollector)
|
||||||
next.ServeHTTP(lrw, r.WithContext(internal.WithLogCollector(r.Context(), logs)))
|
next.ServeHTTP(lrw, r.WithContext(internal.WithLogCollector(r.Context(), logs)))
|
||||||
r.Body = dup
|
r.Body = dup
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/zeromicro/go-zero/core/logx/logtest"
|
||||||
"github.com/zeromicro/go-zero/rest/internal"
|
"github.com/zeromicro/go-zero/rest/internal"
|
||||||
"github.com/zeromicro/go-zero/rest/internal/response"
|
"github.com/zeromicro/go-zero/rest/internal/response"
|
||||||
)
|
)
|
||||||
@@ -86,6 +87,26 @@ func TestLogHandlerSlow(t *testing.T) {
|
|||||||
assert.Equal(t, http.StatusOK, resp.Code)
|
assert.Equal(t, http.StatusOK, resp.Code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDetailedLogHandler_LargeBody(t *testing.T) {
|
||||||
|
lbuf := logtest.NewCollector(t)
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
for i := 0; i < limitDetailedBodyBytes<<2; i++ {
|
||||||
|
buf.WriteByte('a')
|
||||||
|
}
|
||||||
|
|
||||||
|
req := httptest.NewRequest(http.MethodPost, "http://localhost", &buf)
|
||||||
|
h := DetailedLogHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
io.Copy(io.Discard, r.Body)
|
||||||
|
}))
|
||||||
|
resp := httptest.NewRecorder()
|
||||||
|
h.ServeHTTP(resp, req)
|
||||||
|
|
||||||
|
// extra 200 for the length of POST request headers
|
||||||
|
assert.True(t, len(lbuf.Content()) < limitDetailedBodyBytes+200)
|
||||||
|
}
|
||||||
|
|
||||||
func TestDetailedLogHandler_Hijack(t *testing.T) {
|
func TestDetailedLogHandler_Hijack(t *testing.T) {
|
||||||
resp := httptest.NewRecorder()
|
resp := httptest.NewRecorder()
|
||||||
writer := &detailLoggedResponseWriter{
|
writer := &detailLoggedResponseWriter{
|
||||||
@@ -111,6 +132,7 @@ func TestDetailedLogHandler_Hijack(t *testing.T) {
|
|||||||
_, _, _ = writer.Hijack()
|
_, _, _ = writer.Hijack()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetSlowThreshold(t *testing.T) {
|
func TestSetSlowThreshold(t *testing.T) {
|
||||||
assert.Equal(t, defaultSlowThreshold, slowThreshold.Load())
|
assert.Equal(t, defaultSlowThreshold, slowThreshold.Load())
|
||||||
SetSlowThreshold(time.Second)
|
SetSlowThreshold(time.Second)
|
||||||
|
|||||||
Reference in New Issue
Block a user