Skip to content

Commit fa21ecb

Browse files
committed
log: support context-logging
1 parent 80284d4 commit fa21ecb

File tree

5 files changed

+278
-45
lines changed

5 files changed

+278
-45
lines changed

internal/testlog/testlog.go

Lines changed: 83 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ const (
3838
type T interface {
3939
Logf(format string, args ...any)
4040
Helper()
41+
FailNow()
4142
}
4243

4344
// logger implements log.Logger such that all output goes to the unit test log via
@@ -104,65 +105,132 @@ func (l *logger) Handler() slog.Handler {
104105
return l.l.Handler()
105106
}
106107

107-
func (l *logger) Write(level slog.Level, msg string, ctx ...interface{}) {}
108+
func (l *logger) Write(level slog.Level, msg string, args ...interface{}) {
109+
l.t.Helper()
110+
l.mu.Lock()
111+
defer l.mu.Unlock()
112+
l.l.Write(level, msg, args...)
113+
l.flush()
114+
}
115+
116+
func (l *logger) WriteCtx(ctx context.Context, level slog.Level, msg string, args ...interface{}) {
117+
l.t.Helper()
118+
l.mu.Lock()
119+
defer l.mu.Unlock()
120+
l.l.WriteCtx(ctx, level, msg, args...)
121+
l.flush()
122+
}
108123

109124
func (l *logger) Enabled(ctx context.Context, level slog.Level) bool {
110125
return l.l.Enabled(ctx, level)
111126
}
112127

113-
func (l *logger) Trace(msg string, ctx ...interface{}) {
128+
func (l *logger) Trace(msg string, args ...interface{}) {
129+
l.t.Helper()
130+
l.mu.Lock()
131+
defer l.mu.Unlock()
132+
l.l.Trace(msg, args...)
133+
l.flush()
134+
}
135+
136+
func (l *logger) Log(level slog.Level, msg string, args ...interface{}) {
137+
l.t.Helper()
138+
l.mu.Lock()
139+
defer l.mu.Unlock()
140+
l.l.Log(level, msg, args...)
141+
l.flush()
142+
}
143+
144+
func (l *logger) Debug(msg string, args ...interface{}) {
145+
l.t.Helper()
146+
l.mu.Lock()
147+
defer l.mu.Unlock()
148+
l.l.Debug(msg, args...)
149+
l.flush()
150+
}
151+
152+
func (l *logger) Info(msg string, args ...interface{}) {
153+
l.t.Helper()
154+
l.mu.Lock()
155+
defer l.mu.Unlock()
156+
l.l.Info(msg, args...)
157+
l.flush()
158+
}
159+
160+
func (l *logger) Warn(msg string, args ...interface{}) {
161+
l.t.Helper()
162+
l.mu.Lock()
163+
defer l.mu.Unlock()
164+
l.l.Warn(msg, args...)
165+
l.flush()
166+
}
167+
168+
func (l *logger) Error(msg string, args ...interface{}) {
114169
l.t.Helper()
115170
l.mu.Lock()
116171
defer l.mu.Unlock()
117-
l.l.Trace(msg, ctx...)
172+
l.l.Error(msg, args...)
118173
l.flush()
119174
}
120175

121-
func (l *logger) Log(level slog.Level, msg string, ctx ...interface{}) {
176+
func (l *logger) Crit(msg string, args ...interface{}) {
177+
l.t.Helper()
178+
l.mu.Lock()
179+
defer l.mu.Unlock()
180+
l.l.Log(log.LevelCrit, msg, args...) // Bypass the os.Exit by not using the Crit function.
181+
l.flush() // flush critical info to test-logs before exiting
182+
l.t.FailNow()
183+
}
184+
185+
func (l *logger) SetContext(ctx context.Context) {
186+
// no-op: test-logger does not use default contexts.
187+
}
188+
189+
func (l *logger) LogAttrs(ctx context.Context, level slog.Level, msg string, attrs ...slog.Attr) {
122190
l.t.Helper()
123191
l.mu.Lock()
124192
defer l.mu.Unlock()
125-
l.l.Log(level, msg, ctx...)
193+
l.l.LogAttrs(ctx, level, msg, attrs...)
126194
l.flush()
127195
}
128196

129-
func (l *logger) Debug(msg string, ctx ...interface{}) {
197+
func (l *logger) TraceContext(ctx context.Context, msg string, args ...any) {
130198
l.t.Helper()
131199
l.mu.Lock()
132200
defer l.mu.Unlock()
133-
l.l.Debug(msg, ctx...)
201+
l.l.TraceContext(ctx, msg, args...)
134202
l.flush()
135203
}
136204

137-
func (l *logger) Info(msg string, ctx ...interface{}) {
205+
func (l *logger) DebugContext(ctx context.Context, msg string, args ...any) {
138206
l.t.Helper()
139207
l.mu.Lock()
140208
defer l.mu.Unlock()
141-
l.l.Info(msg, ctx...)
209+
l.l.DebugContext(ctx, msg, args...)
142210
l.flush()
143211
}
144212

145-
func (l *logger) Warn(msg string, ctx ...interface{}) {
213+
func (l *logger) InfoContext(ctx context.Context, msg string, args ...any) {
146214
l.t.Helper()
147215
l.mu.Lock()
148216
defer l.mu.Unlock()
149-
l.l.Warn(msg, ctx...)
217+
l.l.InfoContext(ctx, msg, args...)
150218
l.flush()
151219
}
152220

153-
func (l *logger) Error(msg string, ctx ...interface{}) {
221+
func (l *logger) WarnContext(ctx context.Context, msg string, args ...any) {
154222
l.t.Helper()
155223
l.mu.Lock()
156224
defer l.mu.Unlock()
157-
l.l.Error(msg, ctx...)
225+
l.l.WarnContext(ctx, msg, args...)
158226
l.flush()
159227
}
160228

161-
func (l *logger) Crit(msg string, ctx ...interface{}) {
229+
func (l *logger) ErrorContext(ctx context.Context, msg string, args ...any) {
162230
l.t.Helper()
163231
l.mu.Lock()
164232
defer l.mu.Unlock()
165-
l.l.Crit(msg, ctx...)
233+
l.l.ErrorContext(ctx, msg, args...)
166234
l.flush()
167235
}
168236

internal/testlog/testlog_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
"strings"
88
"testing"
99

10+
"github.com/stretchr/testify/require"
11+
1012
"github.com/ethereum/go-ethereum/log"
1113
)
1214

@@ -33,6 +35,10 @@ func (t *mockT) Logf(format string, args ...any) {
3335
}
3436
}
3537

38+
func (t *mockT) FailNow() {
39+
panic("mock FailNow")
40+
}
41+
3642
func TestLogging(t *testing.T) {
3743
tests := []struct {
3844
name string
@@ -65,3 +71,20 @@ func TestLogging(t *testing.T) {
6571
}
6672
}
6773
}
74+
75+
// TestCrit tests that Crit does not os.Exit in testing, and instead fails the test,
76+
// while properly flushing the log output of the critical log.
77+
func TestCrit(t *testing.T) {
78+
outp := bytes.Buffer{}
79+
mt := &mockT{&outp}
80+
l := Logger(mt, log.LevelInfo)
81+
l.Info("hello world", "a", 1)
82+
require.PanicsWithValue(t, "mock FailNow", func() {
83+
l.Crit("bye", "b", 2)
84+
})
85+
got := outp.String()
86+
expected := ` hello world a=1
87+
bye b=2
88+
`
89+
require.Equal(t, expected, got)
90+
}

0 commit comments

Comments
 (0)