Skip to content

Commit

Permalink
log/slog: function argument to Record.Attrs returns bool
Browse files Browse the repository at this point in the history
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 <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
Run-TryBot: Jonathan Amsterdam <jba@google.com>
  • Loading branch information
jba committed Apr 12, 2023
1 parent d528f72 commit f3e6f0f
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 8 deletions.
2 changes: 2 additions & 0 deletions api/next/59060.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pkg log/slog, method (Record) Attrs(func(Attr) bool) #59060

3 changes: 2 additions & 1 deletion src/log/slog/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
3 changes: 2 additions & 1 deletion src/log/slog/internal/benchmarks/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion src/log/slog/internal/benchmarks/handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
11 changes: 8 additions & 3 deletions src/log/slog/record.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
}

Expand Down
15 changes: 13 additions & 2 deletions src/log/slog/record_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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
}

0 comments on commit f3e6f0f

Please sign in to comment.