]> Cypherpunks repositories - gostls13.git/commitdiff
log/slog: add GroupAttrs
authorSean Liao <sean@liao.dev>
Wed, 14 May 2025 20:26:57 +0000 (21:26 +0100)
committerDamien Neil <dneil@google.com>
Wed, 21 May 2025 18:29:28 +0000 (11:29 -0700)
GroupAttrs is a more efficient version of Group
that takes a slice of Attr values.

Fixes #66365

Change-Id: Ic3046704825e17098f2fea5751f2959dce1073e2
Reviewed-on: https://go-review.googlesource.com/c/go/+/672915
Reviewed-by: Jonathan Amsterdam <jba@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
api/next/66365.txt [new file with mode: 0644]
doc/next/6-stdlib/99-minor/log/slog/66365.md [new file with mode: 0644]
src/log/slog/attr.go
src/log/slog/example_test.go

diff --git a/api/next/66365.txt b/api/next/66365.txt
new file mode 100644 (file)
index 0000000..52f1c7e
--- /dev/null
@@ -0,0 +1 @@
+pkg log/slog, func GroupAttrs(string, ...Attr) Attr #66365
diff --git a/doc/next/6-stdlib/99-minor/log/slog/66365.md b/doc/next/6-stdlib/99-minor/log/slog/66365.md
new file mode 100644 (file)
index 0000000..b6b0c81
--- /dev/null
@@ -0,0 +1 @@
+[GroupAttrs] creates a group [Attr] from a slice of [Attr] values.
index 067c537cc973fc2b788c0c4449894ec326f830f3..c592e54eaf9abacc243d932d68c1929f763d8196 100644 (file)
@@ -67,6 +67,15 @@ func Group(key string, args ...any) Attr {
        return Attr{key, GroupValue(argsToAttrSlice(args)...)}
 }
 
+// GroupAttrs returns an Attr for a Group [Value]
+// consisting of the given Attrs.
+//
+// GroupAttrs is a more efficient version of [Group]
+// that accepts only [Attr] values.
+func GroupAttrs(key string, attrs ...Attr) Attr {
+       return Attr{key, GroupValue(attrs...)}
+}
+
 func argsToAttrSlice(args []any) []Attr {
        var (
                attr  Attr
index b03cc01066ccca47f01d3880629ef3c4e42a5a12..c8a05a7bd520add6000ea344e82f788f4454317f 100644 (file)
@@ -5,6 +5,7 @@
 package slog_test
 
 import (
+       "context"
        "log/slog"
        "net/http"
        "os"
@@ -35,3 +36,46 @@ func ExampleGroup() {
        // Output:
        // level=INFO msg=finished req.method=GET req.url=localhost status=200 duration=1s
 }
+
+func ExampleGroupAttrs() {
+       r, _ := http.NewRequest("POST", "localhost", http.NoBody)
+       // ...
+
+       logger := slog.New(
+               slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
+                       Level: slog.LevelDebug,
+                       ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr {
+                               if a.Key == slog.TimeKey && len(groups) == 0 {
+                                       return slog.Attr{}
+                               }
+                               return a
+                       },
+               }),
+       )
+
+       // Use []slog.Attr to accumulate attributes.
+       attrs := []slog.Attr{slog.String("method", r.Method)}
+       attrs = append(attrs, slog.String("url", r.URL.String()))
+
+       if r.Method == "POST" {
+               attrs = append(attrs, slog.Int("content-length", int(r.ContentLength)))
+       }
+
+       // Group the attributes under a key.
+       logger.LogAttrs(context.Background(), slog.LevelInfo,
+               "finished",
+               slog.Int("status", http.StatusOK),
+               slog.GroupAttrs("req", attrs...),
+       )
+
+       // Groups with empty keys are inlined.
+       logger.LogAttrs(context.Background(), slog.LevelInfo,
+               "finished",
+               slog.Int("status", http.StatusOK),
+               slog.GroupAttrs("", attrs...),
+       )
+
+       // Output:
+       // level=INFO msg=finished status=200 req.method=POST req.url=localhost req.content-length=0
+       // level=INFO msg=finished status=200 method=POST url=localhost content-length=0
+}