From f3e6f0f296c5d0a317527ebe6471eedabc408fae Mon Sep 17 00:00:00 2001 From: Jonathan Amsterdam Date: Wed, 12 Apr 2023 09:11:59 -0400 Subject: [PATCH] log/slog: function argument to Record.Attrs returns bool Record.Attrs stops as soon as its argument function returns false. Fixes #59060. Change-Id: I578d64635e0e52b0fcdbc57f6d5a27a6efac8c70 Reviewed-on: https://go-review.googlesource.com/c/go/+/484096 TryBot-Result: Gopher Robot Reviewed-by: Alan Donovan Run-TryBot: Jonathan Amsterdam --- api/next/59060.txt | 2 ++ src/log/slog/handler.go | 3 ++- src/log/slog/internal/benchmarks/handlers.go | 3 ++- src/log/slog/internal/benchmarks/handlers_test.go | 2 +- src/log/slog/record.go | 11 ++++++++--- src/log/slog/record_test.go | 15 +++++++++++++-- 6 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 api/next/59060.txt diff --git a/api/next/59060.txt b/api/next/59060.txt new file mode 100644 index 0000000000..e362452b51 --- /dev/null +++ b/api/next/59060.txt @@ -0,0 +1,2 @@ +pkg log/slog, method (Record) Attrs(func(Attr) bool) #59060 + diff --git a/src/log/slog/handler.go b/src/log/slog/handler.go index 1fd0e76459..d2f919800a 100644 --- a/src/log/slog/handler.go +++ b/src/log/slog/handler.go @@ -330,8 +330,9 @@ func (s *handleState) appendNonBuiltIns(r Record) { defer s.prefix.Free() s.prefix.WriteString(s.h.groupPrefix) s.openGroups() - r.Attrs(func(a Attr) { + r.Attrs(func(a Attr) bool { s.appendAttr(a) + return true }) if s.h.json { // Close all open groups. diff --git a/src/log/slog/internal/benchmarks/handlers.go b/src/log/slog/internal/benchmarks/handlers.go index 4f9213fb5c..091e2ddcca 100644 --- a/src/log/slog/internal/benchmarks/handlers.go +++ b/src/log/slog/internal/benchmarks/handlers.go @@ -47,11 +47,12 @@ func (h *fastTextHandler) Handle(_ context.Context, r slog.Record) error { buf.WriteByte(' ') buf.WriteString("msg=") buf.WriteString(r.Message) - r.Attrs(func(a slog.Attr) { + r.Attrs(func(a slog.Attr) bool { buf.WriteByte(' ') buf.WriteString(a.Key) buf.WriteByte('=') h.appendValue(buf, a.Value) + return true }) buf.WriteByte('\n') _, err := h.w.Write(*buf) diff --git a/src/log/slog/internal/benchmarks/handlers_test.go b/src/log/slog/internal/benchmarks/handlers_test.go index 1777fde368..6c00c80286 100644 --- a/src/log/slog/internal/benchmarks/handlers_test.go +++ b/src/log/slog/internal/benchmarks/handlers_test.go @@ -37,6 +37,6 @@ func TestHandlers(t *testing.T) { func attrSlice(r slog.Record) []slog.Attr { var as []slog.Attr - r.Attrs(func(a slog.Attr) { as = append(as, a) }) + r.Attrs(func(a slog.Attr) bool { as = append(as, a); return true }) return as } diff --git a/src/log/slog/record.go b/src/log/slog/record.go index 0ee2a27f0e..4a5d916119 100644 --- a/src/log/slog/record.go +++ b/src/log/slog/record.go @@ -86,13 +86,18 @@ func (r Record) NumAttrs() int { } // Attrs calls f on each Attr in the Record. +// Iteration stops if f returns false. // The Attrs are already resolved. -func (r Record) Attrs(f func(Attr)) { +func (r Record) Attrs(f func(Attr) bool) { for i := 0; i < r.nFront; i++ { - f(r.front[i]) + if !f(r.front[i]) { + return + } } for _, a := range r.back { - f(a) + if !f(a) { + return + } } } diff --git a/src/log/slog/record_test.go b/src/log/slog/record_test.go index b1410f51ab..c40c6183fa 100644 --- a/src/log/slog/record_test.go +++ b/src/log/slog/record_test.go @@ -23,6 +23,17 @@ func TestRecordAttrs(t *testing.T) { if got := attrsSlice(r); !attrsEqual(got, as) { t.Errorf("got %v, want %v", got, as) } + + // Early return. + var got []Attr + r.Attrs(func(a Attr) bool { + got = append(got, a) + return len(got) < 2 + }) + want := as[:2] + if !attrsEqual(got, want) { + t.Errorf("got %v, want %v", got, want) + } } func TestRecordSourceLine(t *testing.T) { @@ -102,7 +113,7 @@ func newRecordWithAttrs(as []Attr) Record { func attrsSlice(r Record) []Attr { s := make([]Attr, 0, r.NumAttrs()) - r.Attrs(func(a Attr) { s = append(s, a) }) + r.Attrs(func(a Attr) bool { s = append(s, a); return true }) return s } @@ -157,7 +168,7 @@ func BenchmarkRecord(b *testing.B) { for j := 0; j < nAttrs; j++ { r.AddAttrs(Int("k", j)) } - r.Attrs(func(b Attr) { a = b }) + r.Attrs(func(b Attr) bool { a = b; return true }) } _ = a } -- 2.44.0