From 513eb771e2dfd95717f905592a652c77cc906af4 Mon Sep 17 00:00:00 2001 From: Matt Braymer-Hayes Date: Mon, 16 Oct 2023 02:53:36 -0400 Subject: [PATCH 1/2] Make HTTPPayload and associated methods zero-allocation --- go.mod | 1 + http.go | 9 +++------ http_test.go | 9 ++++----- report.go | 2 +- 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index c702650..51deafe 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module go.ajitem.com/zapdriver go 1.17 require ( + github.com/pkg/errors v0.8.1 github.com/stretchr/testify v1.7.0 go.uber.org/zap v1.19.1 ) diff --git a/http.go b/http.go index b5d294f..d40dd5d 100644 --- a/http.go +++ b/http.go @@ -11,7 +11,6 @@ package zapdriver // pipe-1&dateRangeUnbound=backwardInTime import ( - "bytes" "io" "net/http" "strconv" @@ -134,9 +133,8 @@ func NewHTTP(req *http.Request, res *http.Response) *HTTPPayload { } } - buf := &bytes.Buffer{} if req.Body != nil { - n, _ := io.Copy(buf, req.Body) // nolint: gas + n, _ := io.Copy(io.Discard, req.Body) // nolint: gas requestSize += n } @@ -153,8 +151,7 @@ func NewHTTP(req *http.Request, res *http.Response) *HTTPPayload { } if res.Body != nil { - buf.Reset() - n, _ := io.Copy(buf, res.Body) // nolint: gas + n, _ := io.Copy(io.Discard, res.Body) // nolint: gas responseSize += n } @@ -164,7 +161,7 @@ func NewHTTP(req *http.Request, res *http.Response) *HTTPPayload { } // MarshalLogObject implements zapcore.ObjectMarshaller interface. -func (req HTTPPayload) MarshalLogObject(enc zapcore.ObjectEncoder) error { +func (req *HTTPPayload) MarshalLogObject(enc zapcore.ObjectEncoder) error { enc.AddString("requestMethod", req.RequestMethod) enc.AddString("requestUrl", req.RequestURL) enc.AddInt("status", req.Status) diff --git a/http_test.go b/http_test.go index ebc6938..06c6515 100644 --- a/http_test.go +++ b/http_test.go @@ -1,7 +1,7 @@ package zapdriver_test import ( - "io/ioutil" + "io" "net/http" "net/http/httptest" "net/url" @@ -9,7 +9,6 @@ import ( "testing" "github.com/stretchr/testify/assert" - "go.uber.org/zap" "go.ajitem.com/zapdriver" @@ -81,14 +80,14 @@ func TestNewHTTP(t *testing.T) { }, "RequestSize": { - &http.Request{Body: ioutil.NopCloser(strings.NewReader("12345"))}, + &http.Request{Body: io.NopCloser(strings.NewReader("12345"))}, nil, &zapdriver.HTTPPayload{RequestSize: "5", ResponseSize: "0"}, }, "ResponseSize": { nil, - &http.Response{Body: ioutil.NopCloser(strings.NewReader("12345"))}, + &http.Response{Body: io.NopCloser(strings.NewReader("12345"))}, &zapdriver.HTTPPayload{ResponseSize: "5", RequestSize: "0"}, }, @@ -108,7 +107,7 @@ func TestNewHTTP(t *testing.T) { "simple response": { nil, - &http.Response{Body: ioutil.NopCloser(strings.NewReader("12345")), StatusCode: 404}, + &http.Response{Body: io.NopCloser(strings.NewReader("12345")), StatusCode: 404}, &zapdriver.HTTPPayload{RequestSize: "0", ResponseSize: "5", Status: 404}, }, diff --git a/report.go b/report.go index 1bb8ac7..2a4aa5e 100644 --- a/report.go +++ b/report.go @@ -43,7 +43,7 @@ type reportContext struct { // MarshalLogObject implements zapcore.ObjectMarshaller interface. func (context reportContext) MarshalLogObject(enc zapcore.ObjectEncoder) error { - enc.AddObject("reportLocation", context.ReportLocation) + _ = enc.AddObject("reportLocation", context.ReportLocation) return nil } From 09ec6d4303acae853b0d8231c559ce60e2313a5f Mon Sep 17 00:00:00 2001 From: Matt Braymer-Hayes Date: Tue, 17 Oct 2023 12:48:27 -0400 Subject: [PATCH 2/2] =?UTF-8?q?Zero=20allocations=20(save=20=E2=89=88200B?= =?UTF-8?q?=20per=20HTTP=20request)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- http.go | 8 ++++---- http_test.go | 12 +++++++++++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/http.go b/http.go index d40dd5d..4df3c18 100644 --- a/http.go +++ b/http.go @@ -22,7 +22,7 @@ import ( // HTTP adds the correct Stackdriver "HTTP" field. // // see: https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#HttpRequest -func HTTP(req *HTTPPayload) zap.Field { +func HTTP(req HTTPPayload) zap.Field { return zap.Object("httpRequest", req) } @@ -100,7 +100,7 @@ type HTTPPayload struct { // NewHTTP returns a new HTTPPayload struct, based on the passed // in http.Request and http.Response objects. -func NewHTTP(req *http.Request, res *http.Response) *HTTPPayload { +func NewHTTP(req *http.Request, res *http.Response) HTTPPayload { if req == nil { req = &http.Request{} } @@ -109,7 +109,7 @@ func NewHTTP(req *http.Request, res *http.Response) *HTTPPayload { res = &http.Response{} } - sdreq := &HTTPPayload{ + sdreq := HTTPPayload{ RequestMethod: req.Method, Status: res.StatusCode, UserAgent: req.UserAgent(), @@ -161,7 +161,7 @@ func NewHTTP(req *http.Request, res *http.Response) *HTTPPayload { } // MarshalLogObject implements zapcore.ObjectMarshaller interface. -func (req *HTTPPayload) MarshalLogObject(enc zapcore.ObjectEncoder) error { +func (req HTTPPayload) MarshalLogObject(enc zapcore.ObjectEncoder) error { enc.AddString("requestMethod", req.RequestMethod) enc.AddString("requestUrl", req.RequestURL) enc.AddInt("status", req.Status) diff --git a/http_test.go b/http_test.go index 06c6515..1524594 100644 --- a/http_test.go +++ b/http_test.go @@ -14,10 +14,20 @@ import ( "go.ajitem.com/zapdriver" ) +func BenchmarkHTTP(b *testing.B) { + b.ReportAllocs() + b.RunParallel(func(b *testing.PB) { + for b.Next() { + p := zapdriver.NewHTTP(nil, nil) + _ = zapdriver.HTTP(p) + } + }) +} + func TestHTTP(t *testing.T) { t.Parallel() - req := &zapdriver.HTTPPayload{} + var req zapdriver.HTTPPayload field := zapdriver.HTTP(req) assert.Equal(t, zap.Object("httpRequest", req), field)