Skip to content

Commit 8f714b1

Browse files
committed
log/slog: add DiscardHandler
This adds a package-level variable, slog.Discard, which is a slog.Handler which performs no output. This serves a similar purpose to io.Discard. Fixes golang#62005
1 parent c96939f commit 8f714b1

File tree

5 files changed

+76
-11
lines changed

5 files changed

+76
-11
lines changed

api/next/62005.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pkg log/slog, var DiscardHandler Handler #62005

src/log/slog/discard.go

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package slog
2+
3+
import "context"
4+
5+
// DiscardHandler discards all log output.
6+
// DiscardHandler.Enabled returns false for all Levels.
7+
var DiscardHandler Handler = discardHandler{}
8+
9+
type discardHandler struct{}
10+
11+
func (dh discardHandler) Enabled(context.Context, Level) bool { return false }
12+
func (dh discardHandler) Handle(context.Context, Record) error { return nil }
13+
func (dh discardHandler) WithAttrs(attrs []Attr) Handler { return dh }
14+
func (dh discardHandler) WithGroup(name string) Handler { return dh }

src/log/slog/discard_test.go

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package slog
2+
3+
import (
4+
"context"
5+
"os"
6+
"testing"
7+
"time"
8+
)
9+
10+
func TestDiscardHandler(t *testing.T) {
11+
ctx := context.Background()
12+
stdout, stderr := os.Stdout, os.Stderr
13+
os.Stdout, os.Stderr = nil, nil // panic on write
14+
t.Cleanup(func() {
15+
os.Stdout, os.Stderr = stdout, stderr
16+
})
17+
18+
// Just ensure nothing panics during normal usage
19+
l := New(DiscardHandler)
20+
l.Info("msg", "a", 1, "b", 2)
21+
l.Debug("bg", Int("a", 1), "b", 2)
22+
l.Warn("w", Duration("dur", 3*time.Second))
23+
l.Error("bad", "a", 1)
24+
l.Log(ctx, LevelWarn+1, "w", Int("a", 1), String("b", "two"))
25+
l.LogAttrs(ctx, LevelInfo+1, "a b c", Int("a", 1), String("b", "two"))
26+
l.Info("info", "a", []Attr{Int("i", 1)})
27+
l.Info("info", "a", GroupValue(Int("i", 1)))
28+
}

src/log/slog/example_discard_test.go

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package slog_test
2+
3+
import (
4+
"log/slog"
5+
"log/slog/internal/slogtest"
6+
"os"
7+
)
8+
9+
func ExampleDiscardHandler() {
10+
// A slog.TextHandler will output logs
11+
logger1 := slog.New(slog.NewTextHandler(
12+
os.Stdout,
13+
&slog.HandlerOptions{ReplaceAttr: slogtest.RemoveTime},
14+
))
15+
logger1.Info("message 1")
16+
17+
// A slog.DiscardHandler will discard all messages
18+
logger2 := slog.New(slog.DiscardHandler)
19+
logger2.Info("message 2")
20+
21+
// Output:
22+
// level=INFO msg="message 1"
23+
}

src/log/slog/logger_test.go

+10-11
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ func TestCallDepth(t *testing.T) {
231231

232232
func TestAlloc(t *testing.T) {
233233
ctx := context.Background()
234-
dl := New(discardHandler{})
234+
dl := New(discardTestHandler{})
235235
defer SetDefault(Default()) // restore
236236
SetDefault(dl)
237237

@@ -258,7 +258,7 @@ func TestAlloc(t *testing.T) {
258258
})
259259
})
260260
t.Run("2 pairs disabled inline", func(t *testing.T) {
261-
l := New(discardHandler{disabled: true})
261+
l := New(DiscardHandler)
262262
s := "abc"
263263
i := 2000
264264
wantAllocs(t, 2, func() {
@@ -269,7 +269,7 @@ func TestAlloc(t *testing.T) {
269269
})
270270
})
271271
t.Run("2 pairs disabled", func(t *testing.T) {
272-
l := New(discardHandler{disabled: true})
272+
l := New(DiscardHandler)
273273
s := "abc"
274274
i := 2000
275275
wantAllocs(t, 0, func() {
@@ -305,7 +305,7 @@ func TestAlloc(t *testing.T) {
305305
})
306306
})
307307
t.Run("attrs3 disabled", func(t *testing.T) {
308-
logger := New(discardHandler{disabled: true})
308+
logger := New(DiscardHandler)
309309
wantAllocs(t, 0, func() {
310310
logger.LogAttrs(ctx, LevelInfo, "hello", Int("a", 1), String("b", "two"), Duration("c", time.Second))
311311
})
@@ -568,18 +568,17 @@ func (c *captureHandler) clear() {
568568
c.r = Record{}
569569
}
570570

571-
type discardHandler struct {
572-
disabled bool
573-
attrs []Attr
571+
type discardTestHandler struct {
572+
attrs []Attr
574573
}
575574

576-
func (d discardHandler) Enabled(context.Context, Level) bool { return !d.disabled }
577-
func (discardHandler) Handle(context.Context, Record) error { return nil }
578-
func (d discardHandler) WithAttrs(as []Attr) Handler {
575+
func (d discardTestHandler) Enabled(context.Context, Level) bool { return true }
576+
func (discardTestHandler) Handle(context.Context, Record) error { return nil }
577+
func (d discardTestHandler) WithAttrs(as []Attr) Handler {
579578
d.attrs = concat(d.attrs, as)
580579
return d
581580
}
582-
func (h discardHandler) WithGroup(name string) Handler {
581+
func (h discardTestHandler) WithGroup(name string) Handler {
583582
return h
584583
}
585584

0 commit comments

Comments
 (0)