Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions promslog/slog.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,8 @@ func New(config *Config) *slog.Logger {
return slog.New(slog.NewTextHandler(config.Writer, logHandlerOpts))
}

// NewNopLogger is a convenience function to return an slog.Logger that writes
// to io.Discard.
// NewNopLogger is a convenience function to return an slog.Logger that
// discards all log records.
func NewNopLogger() *slog.Logger {
return New(&Config{Writer: io.Discard})
return slog.New(slog.DiscardHandler)
}
32 changes: 32 additions & 0 deletions promslog/slog_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,3 +254,35 @@ func TestReservedKeys(t *testing.T) {
})
}
}

type expensiveValuer struct {
called *bool
}

func (v expensiveValuer) LogValue() slog.Value {
*v.called = true
return slog.StringValue("expensive")
}

func TestNewNopLogger(t *testing.T) {
logger := NewNopLogger()

for _, lvl := range []slog.Level{slog.LevelDebug, slog.LevelInfo, slog.LevelWarn, slog.LevelError} {
require.Falsef(t, logger.Enabled(context.Background(), lvl), "nop logger must be disabled for level %s", lvl)
}

// Arguments must never be evaluated, so that using a nop logger in a hot
// path stays free.
called := false
logger.Info("test", "expensive", expensiveValuer{called: &called})
require.Falsef(t, called, "nop logger must not evaluate log arguments")
}

func BenchmarkNopLogger(b *testing.B) {
logger := NewNopLogger()
value := struct{ Field string }{Field: "value"}

for b.Loop() {
logger.Info("test", "key", value)
}
}
Loading