1
0
mirror of https://github.com/golang/go synced 2024-11-23 05:10:09 -07:00

log/slog: replace nil contexts with context.Background()

Passing nil for a context is discouraged. We should avoid it.

Fixes #61219.

Change-Id: I664387070aacb56af580b6b0791ca40982d2a711
Reviewed-on: https://go-review.googlesource.com/c/go/+/508437
Run-TryBot: Jonathan Amsterdam <jba@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
Jonathan Amsterdam 2023-07-07 09:11:46 -04:00
parent 3f8b04bfb5
commit 651869716a
6 changed files with 42 additions and 37 deletions

View File

@ -206,7 +206,7 @@ keys and values; this allows it, too, to avoid allocation.
The call The call
logger.LogAttrs(nil, slog.LevelInfo, "hello", slog.Int("count", 3)) logger.LogAttrs(ctx, slog.LevelInfo, "hello", slog.Int("count", 3))
is the most efficient way to achieve the same output as is the most efficient way to achieve the same output as

View File

@ -5,6 +5,7 @@
package slog_test package slog_test
import ( import (
"context"
"log/slog" "log/slog"
"os" "os"
) )
@ -72,13 +73,14 @@ func ExampleHandlerOptions_customLevels() {
}) })
logger := slog.New(th) logger := slog.New(th)
logger.Log(nil, LevelEmergency, "missing pilots") ctx := context.Background()
logger.Log(ctx, LevelEmergency, "missing pilots")
logger.Error("failed to start engines", "err", "missing fuel") logger.Error("failed to start engines", "err", "missing fuel")
logger.Warn("falling back to default value") logger.Warn("falling back to default value")
logger.Log(nil, LevelNotice, "all systems are running") logger.Log(ctx, LevelNotice, "all systems are running")
logger.Info("initiating launch") logger.Info("initiating launch")
logger.Debug("starting background job") logger.Debug("starting background job")
logger.Log(nil, LevelTrace, "button clicked") logger.Log(ctx, LevelTrace, "button clicked")
// Output: // Output:
// sev=EMERGENCY msg="missing pilots" // sev=EMERGENCY msg="missing pilots"

View File

@ -108,8 +108,6 @@ func TestDefaultHandle(t *testing.T) {
// Verify the common parts of TextHandler and JSONHandler. // Verify the common parts of TextHandler and JSONHandler.
func TestJSONAndTextHandlers(t *testing.T) { func TestJSONAndTextHandlers(t *testing.T) {
ctx := context.Background()
// remove all Attrs // remove all Attrs
removeAll := func(_ []string, a Attr) Attr { return Attr{} } removeAll := func(_ []string, a Attr) Attr { return Attr{} }
@ -412,7 +410,7 @@ func TestJSONAndTextHandlers(t *testing.T) {
h = test.with(h) h = test.with(h)
} }
buf.Reset() buf.Reset()
if err := h.Handle(ctx, r); err != nil { if err := h.Handle(nil, r); err != nil {
t.Fatal(err) t.Fatal(err)
} }
want := strings.ReplaceAll(handler.want, "$LINE", line) want := strings.ReplaceAll(handler.want, "$LINE", line)

View File

@ -174,6 +174,7 @@ func BenchmarkJSONHandler(b *testing.B) {
}}, }},
} { } {
b.Run(bench.name, func(b *testing.B) { b.Run(bench.name, func(b *testing.B) {
ctx := context.Background()
l := New(NewJSONHandler(io.Discard, &bench.opts)).With( l := New(NewJSONHandler(io.Discard, &bench.opts)).With(
String("program", "my-test-program"), String("program", "my-test-program"),
String("package", "log/slog"), String("package", "log/slog"),
@ -182,7 +183,7 @@ func BenchmarkJSONHandler(b *testing.B) {
b.ReportAllocs() b.ReportAllocs()
b.ResetTimer() b.ResetTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
l.LogAttrs(nil, LevelInfo, "this is a typical log message", l.LogAttrs(ctx, LevelInfo, "this is a typical log message",
String("module", "github.com/google/go-cmp"), String("module", "github.com/google/go-cmp"),
String("version", "v1.23.4"), String("version", "v1.23.4"),
Int("count", 23), Int("count", 23),
@ -238,12 +239,13 @@ func BenchmarkPreformatting(b *testing.B) {
{"struct", io.Discard, structAttrs}, {"struct", io.Discard, structAttrs},
{"struct file", outFile, structAttrs}, {"struct file", outFile, structAttrs},
} { } {
ctx := context.Background()
b.Run(bench.name, func(b *testing.B) { b.Run(bench.name, func(b *testing.B) {
l := New(NewJSONHandler(bench.wc, nil)).With(bench.attrs...) l := New(NewJSONHandler(bench.wc, nil)).With(bench.attrs...)
b.ReportAllocs() b.ReportAllocs()
b.ResetTimer() b.ResetTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
l.LogAttrs(nil, LevelInfo, "this is a typical log message", l.LogAttrs(ctx, LevelInfo, "this is a typical log message",
String("module", "github.com/google/go-cmp"), String("module", "github.com/google/go-cmp"),
String("version", "v1.23.4"), String("version", "v1.23.4"),
Int("count", 23), Int("count", 23),

View File

@ -165,7 +165,7 @@ func (l *Logger) LogAttrs(ctx context.Context, level Level, msg string, attrs ..
// Debug logs at LevelDebug. // Debug logs at LevelDebug.
func (l *Logger) Debug(msg string, args ...any) { func (l *Logger) Debug(msg string, args ...any) {
l.log(nil, LevelDebug, msg, args...) l.log(context.Background(), LevelDebug, msg, args...)
} }
// DebugContext logs at LevelDebug with the given context. // DebugContext logs at LevelDebug with the given context.
@ -175,7 +175,7 @@ func (l *Logger) DebugContext(ctx context.Context, msg string, args ...any) {
// Info logs at LevelInfo. // Info logs at LevelInfo.
func (l *Logger) Info(msg string, args ...any) { func (l *Logger) Info(msg string, args ...any) {
l.log(nil, LevelInfo, msg, args...) l.log(context.Background(), LevelInfo, msg, args...)
} }
// InfoContext logs at LevelInfo with the given context. // InfoContext logs at LevelInfo with the given context.
@ -185,7 +185,7 @@ func (l *Logger) InfoContext(ctx context.Context, msg string, args ...any) {
// Warn logs at LevelWarn. // Warn logs at LevelWarn.
func (l *Logger) Warn(msg string, args ...any) { func (l *Logger) Warn(msg string, args ...any) {
l.log(nil, LevelWarn, msg, args...) l.log(context.Background(), LevelWarn, msg, args...)
} }
// WarnContext logs at LevelWarn with the given context. // WarnContext logs at LevelWarn with the given context.
@ -195,7 +195,7 @@ func (l *Logger) WarnContext(ctx context.Context, msg string, args ...any) {
// Error logs at LevelError. // Error logs at LevelError.
func (l *Logger) Error(msg string, args ...any) { func (l *Logger) Error(msg string, args ...any) {
l.log(nil, LevelError, msg, args...) l.log(context.Background(), LevelError, msg, args...)
} }
// ErrorContext logs at LevelError with the given context. // ErrorContext logs at LevelError with the given context.
@ -247,7 +247,7 @@ func (l *Logger) logAttrs(ctx context.Context, level Level, msg string, attrs ..
// Debug calls Logger.Debug on the default logger. // Debug calls Logger.Debug on the default logger.
func Debug(msg string, args ...any) { func Debug(msg string, args ...any) {
Default().log(nil, LevelDebug, msg, args...) Default().log(context.Background(), LevelDebug, msg, args...)
} }
// DebugContext calls Logger.DebugContext on the default logger. // DebugContext calls Logger.DebugContext on the default logger.
@ -257,7 +257,7 @@ func DebugContext(ctx context.Context, msg string, args ...any) {
// Info calls Logger.Info on the default logger. // Info calls Logger.Info on the default logger.
func Info(msg string, args ...any) { func Info(msg string, args ...any) {
Default().log(nil, LevelInfo, msg, args...) Default().log(context.Background(), LevelInfo, msg, args...)
} }
// InfoContext calls Logger.InfoContext on the default logger. // InfoContext calls Logger.InfoContext on the default logger.
@ -267,7 +267,7 @@ func InfoContext(ctx context.Context, msg string, args ...any) {
// Warn calls Logger.Warn on the default logger. // Warn calls Logger.Warn on the default logger.
func Warn(msg string, args ...any) { func Warn(msg string, args ...any) {
Default().log(nil, LevelWarn, msg, args...) Default().log(context.Background(), LevelWarn, msg, args...)
} }
// WarnContext calls Logger.WarnContext on the default logger. // WarnContext calls Logger.WarnContext on the default logger.
@ -277,7 +277,7 @@ func WarnContext(ctx context.Context, msg string, args ...any) {
// Error calls Logger.Error on the default logger. // Error calls Logger.Error on the default logger.
func Error(msg string, args ...any) { func Error(msg string, args ...any) {
Default().log(nil, LevelError, msg, args...) Default().log(context.Background(), LevelError, msg, args...)
} }
// ErrorContext calls Logger.ErrorContext on the default logger. // ErrorContext calls Logger.ErrorContext on the default logger.

View File

@ -25,6 +25,7 @@ import (
const timeRE = `\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}(Z|[+-]\d{2}:\d{2})` const timeRE = `\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}(Z|[+-]\d{2}:\d{2})`
func TestLogTextHandler(t *testing.T) { func TestLogTextHandler(t *testing.T) {
ctx := context.Background()
var buf bytes.Buffer var buf bytes.Buffer
l := New(NewTextHandler(&buf, nil)) l := New(NewTextHandler(&buf, nil))
@ -51,10 +52,10 @@ func TestLogTextHandler(t *testing.T) {
l.Error("bad", "a", 1) l.Error("bad", "a", 1)
check(`level=ERROR msg=bad a=1`) check(`level=ERROR msg=bad a=1`)
l.Log(nil, LevelWarn+1, "w", Int("a", 1), String("b", "two")) l.Log(ctx, LevelWarn+1, "w", Int("a", 1), String("b", "two"))
check(`level=WARN\+1 msg=w a=1 b=two`) check(`level=WARN\+1 msg=w a=1 b=two`)
l.LogAttrs(nil, LevelInfo+1, "a b c", Int("a", 1), String("b", "two")) l.LogAttrs(ctx, LevelInfo+1, "a b c", Int("a", 1), String("b", "two"))
check(`level=INFO\+1 msg="a b c" a=1 b=two`) check(`level=INFO\+1 msg="a b c" a=1 b=two`)
l.Info("info", "a", []Attr{Int("i", 1)}) l.Info("info", "a", []Attr{Int("i", 1)})
@ -156,6 +157,7 @@ func TestAttrs(t *testing.T) {
} }
func TestCallDepth(t *testing.T) { func TestCallDepth(t *testing.T) {
ctx := context.Background()
h := &captureHandler{} h := &captureHandler{}
var startLine int var startLine int
@ -181,9 +183,9 @@ func TestCallDepth(t *testing.T) {
startLine = f.Line + 4 startLine = f.Line + 4
// Do not change the number of lines between here and the call to check(0). // Do not change the number of lines between here and the call to check(0).
logger.Log(nil, LevelInfo, "") logger.Log(ctx, LevelInfo, "")
check(0) check(0)
logger.LogAttrs(nil, LevelInfo, "") logger.LogAttrs(ctx, LevelInfo, "")
check(1) check(1)
logger.Debug("") logger.Debug("")
check(2) check(2)
@ -201,13 +203,14 @@ func TestCallDepth(t *testing.T) {
check(8) check(8)
Error("") Error("")
check(9) check(9)
Log(nil, LevelInfo, "") Log(ctx, LevelInfo, "")
check(10) check(10)
LogAttrs(nil, LevelInfo, "") LogAttrs(ctx, LevelInfo, "")
check(11) check(11)
} }
func TestAlloc(t *testing.T) { func TestAlloc(t *testing.T) {
ctx := context.Background()
dl := New(discardHandler{}) dl := New(discardHandler{})
defer SetDefault(Default()) // restore defer SetDefault(Default()) // restore
SetDefault(dl) SetDefault(dl)
@ -222,7 +225,7 @@ func TestAlloc(t *testing.T) {
wantAllocs(t, 0, func() { dl.Info("hello") }) wantAllocs(t, 0, func() { dl.Info("hello") })
}) })
t.Run("logger.Log", func(t *testing.T) { t.Run("logger.Log", func(t *testing.T) {
wantAllocs(t, 0, func() { dl.Log(nil, LevelDebug, "hello") }) wantAllocs(t, 0, func() { dl.Log(ctx, LevelDebug, "hello") })
}) })
t.Run("2 pairs", func(t *testing.T) { t.Run("2 pairs", func(t *testing.T) {
s := "abc" s := "abc"
@ -239,7 +242,7 @@ func TestAlloc(t *testing.T) {
s := "abc" s := "abc"
i := 2000 i := 2000
wantAllocs(t, 2, func() { wantAllocs(t, 2, func() {
l.Log(nil, LevelInfo, "hello", l.Log(ctx, LevelInfo, "hello",
"n", i, "n", i,
"s", s, "s", s,
) )
@ -250,8 +253,8 @@ func TestAlloc(t *testing.T) {
s := "abc" s := "abc"
i := 2000 i := 2000
wantAllocs(t, 0, func() { wantAllocs(t, 0, func() {
if l.Enabled(nil, LevelInfo) { if l.Enabled(ctx, LevelInfo) {
l.Log(nil, LevelInfo, "hello", l.Log(ctx, LevelInfo, "hello",
"n", i, "n", i,
"s", s, "s", s,
) )
@ -273,30 +276,30 @@ func TestAlloc(t *testing.T) {
wantAllocs(t, 0, func() { dl.Info("", "error", io.EOF) }) wantAllocs(t, 0, func() { dl.Info("", "error", io.EOF) })
}) })
t.Run("attrs1", func(t *testing.T) { t.Run("attrs1", func(t *testing.T) {
wantAllocs(t, 0, func() { dl.LogAttrs(nil, LevelInfo, "", Int("a", 1)) }) wantAllocs(t, 0, func() { dl.LogAttrs(ctx, LevelInfo, "", Int("a", 1)) })
wantAllocs(t, 0, func() { dl.LogAttrs(nil, LevelInfo, "", Any("error", io.EOF)) }) wantAllocs(t, 0, func() { dl.LogAttrs(ctx, LevelInfo, "", Any("error", io.EOF)) })
}) })
t.Run("attrs3", func(t *testing.T) { t.Run("attrs3", func(t *testing.T) {
wantAllocs(t, 0, func() { wantAllocs(t, 0, func() {
dl.LogAttrs(nil, LevelInfo, "hello", Int("a", 1), String("b", "two"), Duration("c", time.Second)) dl.LogAttrs(ctx, LevelInfo, "hello", Int("a", 1), String("b", "two"), Duration("c", time.Second))
}) })
}) })
t.Run("attrs3 disabled", func(t *testing.T) { t.Run("attrs3 disabled", func(t *testing.T) {
logger := New(discardHandler{disabled: true}) logger := New(discardHandler{disabled: true})
wantAllocs(t, 0, func() { wantAllocs(t, 0, func() {
logger.LogAttrs(nil, LevelInfo, "hello", Int("a", 1), String("b", "two"), Duration("c", time.Second)) logger.LogAttrs(ctx, LevelInfo, "hello", Int("a", 1), String("b", "two"), Duration("c", time.Second))
}) })
}) })
t.Run("attrs6", func(t *testing.T) { t.Run("attrs6", func(t *testing.T) {
wantAllocs(t, 1, func() { wantAllocs(t, 1, func() {
dl.LogAttrs(nil, LevelInfo, "hello", dl.LogAttrs(ctx, LevelInfo, "hello",
Int("a", 1), String("b", "two"), Duration("c", time.Second), Int("a", 1), String("b", "two"), Duration("c", time.Second),
Int("d", 1), String("e", "two"), Duration("f", time.Second)) Int("d", 1), String("e", "two"), Duration("f", time.Second))
}) })
}) })
t.Run("attrs9", func(t *testing.T) { t.Run("attrs9", func(t *testing.T) {
wantAllocs(t, 1, func() { wantAllocs(t, 1, func() {
dl.LogAttrs(nil, LevelInfo, "hello", dl.LogAttrs(ctx, LevelInfo, "hello",
Int("a", 1), String("b", "two"), Duration("c", time.Second), Int("a", 1), String("b", "two"), Duration("c", time.Second),
Int("d", 1), String("e", "two"), Duration("f", time.Second), Int("d", 1), String("e", "two"), Duration("f", time.Second),
Int("d", 1), String("e", "two"), Duration("f", time.Second)) Int("d", 1), String("e", "two"), Duration("f", time.Second))
@ -511,27 +514,27 @@ func BenchmarkNopLog(b *testing.B) {
b.Run("no attrs", func(b *testing.B) { b.Run("no attrs", func(b *testing.B) {
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
l.LogAttrs(nil, LevelInfo, "msg") l.LogAttrs(ctx, LevelInfo, "msg")
} }
}) })
b.Run("attrs", func(b *testing.B) { b.Run("attrs", func(b *testing.B) {
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
l.LogAttrs(nil, LevelInfo, "msg", Int("a", 1), String("b", "two"), Bool("c", true)) l.LogAttrs(ctx, LevelInfo, "msg", Int("a", 1), String("b", "two"), Bool("c", true))
} }
}) })
b.Run("attrs-parallel", func(b *testing.B) { b.Run("attrs-parallel", func(b *testing.B) {
b.ReportAllocs() b.ReportAllocs()
b.RunParallel(func(pb *testing.PB) { b.RunParallel(func(pb *testing.PB) {
for pb.Next() { for pb.Next() {
l.LogAttrs(nil, LevelInfo, "msg", Int("a", 1), String("b", "two"), Bool("c", true)) l.LogAttrs(ctx, LevelInfo, "msg", Int("a", 1), String("b", "two"), Bool("c", true))
} }
}) })
}) })
b.Run("keys-values", func(b *testing.B) { b.Run("keys-values", func(b *testing.B) {
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
l.Log(nil, LevelInfo, "msg", "a", 1, "b", "two", "c", true) l.Log(ctx, LevelInfo, "msg", "a", 1, "b", "two", "c", true)
} }
}) })
b.Run("WithContext", func(b *testing.B) { b.Run("WithContext", func(b *testing.B) {