Skip to content

Commit 434fa67

Browse files
authored
feat(v2): pass logger to downstream via context (#474)
1 parent f5e5a13 commit 434fa67

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

v2/callctx/callctx.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ package callctx
3535
import (
3636
"context"
3737
"fmt"
38+
"log/slog"
3839
)
3940

4041
const (
@@ -125,3 +126,21 @@ func TelemetryFromContext(ctx context.Context, key string) (string, bool) {
125126
val, ok := ctx.Value(telemetryKey(key)).(string)
126127
return val, ok
127128
}
129+
130+
// loggerKey is a private type used to store/retrieve the logger context value.
131+
type loggerContextKey string
132+
133+
const loggerCKey = loggerContextKey("logger")
134+
135+
// WithLogger injects a slog.Logger into the context. This logger will be
136+
// extracted by the client library or transport wrappers to emit logs.
137+
func WithLogger(ctx context.Context, logger *slog.Logger) context.Context {
138+
return context.WithValue(ctx, loggerCKey, logger)
139+
}
140+
141+
// LoggerFromContext extracts a slog.Logger from the context.
142+
// The returned bool indicates whether a logger was found.
143+
func LoggerFromContext(ctx context.Context) (*slog.Logger, bool) {
144+
logger, ok := ctx.Value(loggerCKey).(*slog.Logger)
145+
return logger, ok
146+
}

v2/callctx/callctx_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@
3030
package callctx
3131

3232
import (
33+
"bytes"
3334
"context"
35+
"log/slog"
3436
"sync"
3537
"testing"
3638

@@ -122,3 +124,23 @@ func TestSetHeaders_race(t *testing.T) {
122124
}
123125
wg.Wait()
124126
}
127+
128+
func TestLoggerFromContext(t *testing.T) {
129+
ctx := context.Background()
130+
131+
// Should not find a logger in an empty context
132+
l, ok := LoggerFromContext(ctx)
133+
if ok || l != nil {
134+
t.Errorf("LoggerFromContext(ctx) = %v, %v; want nil, false", l, ok)
135+
}
136+
137+
// Should extract the exact logger that was injected
138+
var logOutput bytes.Buffer
139+
injectedLogger := slog.New(slog.NewTextHandler(&logOutput, nil))
140+
ctx = WithLogger(ctx, injectedLogger)
141+
142+
extractedLogger, ok := LoggerFromContext(ctx)
143+
if !ok || extractedLogger != injectedLogger {
144+
t.Errorf("LoggerFromContext(ctx) = %v, %v; want %v, true", extractedLogger, ok, injectedLogger)
145+
}
146+
}

0 commit comments

Comments
 (0)