Skip to content

Commit

Permalink
log/slog: add DiscardHandler
Browse files Browse the repository at this point in the history
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
  • Loading branch information
earthboundkid committed Nov 12, 2024
1 parent c96939f commit 8f714b1
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 11 deletions.
1 change: 1 addition & 0 deletions api/next/62005.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pkg log/slog, var DiscardHandler Handler #62005
14 changes: 14 additions & 0 deletions src/log/slog/discard.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package slog

import "context"

// DiscardHandler discards all log output.
// DiscardHandler.Enabled returns false for all Levels.
var DiscardHandler Handler = discardHandler{}

type discardHandler struct{}

func (dh discardHandler) Enabled(context.Context, Level) bool { return false }
func (dh discardHandler) Handle(context.Context, Record) error { return nil }
func (dh discardHandler) WithAttrs(attrs []Attr) Handler { return dh }
func (dh discardHandler) WithGroup(name string) Handler { return dh }
28 changes: 28 additions & 0 deletions src/log/slog/discard_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package slog

import (
"context"
"os"
"testing"
"time"
)

func TestDiscardHandler(t *testing.T) {
ctx := context.Background()
stdout, stderr := os.Stdout, os.Stderr
os.Stdout, os.Stderr = nil, nil // panic on write
t.Cleanup(func() {
os.Stdout, os.Stderr = stdout, stderr
})

// Just ensure nothing panics during normal usage
l := New(DiscardHandler)
l.Info("msg", "a", 1, "b", 2)
l.Debug("bg", Int("a", 1), "b", 2)
l.Warn("w", Duration("dur", 3*time.Second))
l.Error("bad", "a", 1)
l.Log(ctx, LevelWarn+1, "w", Int("a", 1), String("b", "two"))
l.LogAttrs(ctx, LevelInfo+1, "a b c", Int("a", 1), String("b", "two"))
l.Info("info", "a", []Attr{Int("i", 1)})
l.Info("info", "a", GroupValue(Int("i", 1)))
}
23 changes: 23 additions & 0 deletions src/log/slog/example_discard_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package slog_test

import (
"log/slog"
"log/slog/internal/slogtest"
"os"
)

func ExampleDiscardHandler() {
// A slog.TextHandler will output logs
logger1 := slog.New(slog.NewTextHandler(
os.Stdout,
&slog.HandlerOptions{ReplaceAttr: slogtest.RemoveTime},
))
logger1.Info("message 1")

// A slog.DiscardHandler will discard all messages
logger2 := slog.New(slog.DiscardHandler)
logger2.Info("message 2")

// Output:
// level=INFO msg="message 1"
}
21 changes: 10 additions & 11 deletions src/log/slog/logger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ func TestCallDepth(t *testing.T) {

func TestAlloc(t *testing.T) {
ctx := context.Background()
dl := New(discardHandler{})
dl := New(discardTestHandler{})
defer SetDefault(Default()) // restore
SetDefault(dl)

Expand All @@ -258,7 +258,7 @@ func TestAlloc(t *testing.T) {
})
})
t.Run("2 pairs disabled inline", func(t *testing.T) {
l := New(discardHandler{disabled: true})
l := New(DiscardHandler)
s := "abc"
i := 2000
wantAllocs(t, 2, func() {
Expand All @@ -269,7 +269,7 @@ func TestAlloc(t *testing.T) {
})
})
t.Run("2 pairs disabled", func(t *testing.T) {
l := New(discardHandler{disabled: true})
l := New(DiscardHandler)
s := "abc"
i := 2000
wantAllocs(t, 0, func() {
Expand Down Expand Up @@ -305,7 +305,7 @@ func TestAlloc(t *testing.T) {
})
})
t.Run("attrs3 disabled", func(t *testing.T) {
logger := New(discardHandler{disabled: true})
logger := New(DiscardHandler)
wantAllocs(t, 0, func() {
logger.LogAttrs(ctx, LevelInfo, "hello", Int("a", 1), String("b", "two"), Duration("c", time.Second))
})
Expand Down Expand Up @@ -568,18 +568,17 @@ func (c *captureHandler) clear() {
c.r = Record{}
}

type discardHandler struct {
disabled bool
attrs []Attr
type discardTestHandler struct {
attrs []Attr
}

func (d discardHandler) Enabled(context.Context, Level) bool { return !d.disabled }
func (discardHandler) Handle(context.Context, Record) error { return nil }
func (d discardHandler) WithAttrs(as []Attr) Handler {
func (d discardTestHandler) Enabled(context.Context, Level) bool { return true }
func (discardTestHandler) Handle(context.Context, Record) error { return nil }
func (d discardTestHandler) WithAttrs(as []Attr) Handler {
d.attrs = concat(d.attrs, as)
return d
}
func (h discardHandler) WithGroup(name string) Handler {
func (h discardTestHandler) WithGroup(name string) Handler {
return h
}

Expand Down

0 comments on commit 8f714b1

Please sign in to comment.