mirror of
https://github.com/Noooste/garage-ui.git
synced 2026-08-09 13:09:24 +00:00
feat(logger): add IntoCtx/FromCtx for per-request loggers
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
// ctxKey is unexported so other packages can't collide.
|
||||
type ctxKey struct{}
|
||||
|
||||
// IntoCtx returns a new context carrying the given logger. Retrieve it later
|
||||
// with FromCtx. Middleware that builds a per-request logger should call this
|
||||
// once per request.
|
||||
func IntoCtx(ctx context.Context, l zerolog.Logger) context.Context {
|
||||
return context.WithValue(ctx, ctxKey{}, l)
|
||||
}
|
||||
|
||||
// FromCtx returns the logger bound to ctx. If no logger is bound (e.g. the
|
||||
// call is outside any middleware, or ctx is nil), it returns the global
|
||||
// logger. Never returns a zero-value zerolog.Logger.
|
||||
func FromCtx(ctx context.Context) zerolog.Logger {
|
||||
if ctx != nil {
|
||||
if l, ok := ctx.Value(ctxKey{}).(zerolog.Logger); ok {
|
||||
return l
|
||||
}
|
||||
}
|
||||
return Get().Logger
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
func TestFromCtx_ReturnsBoundLogger(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
l := zerolog.New(&buf).With().Str("request_id", "req-1").Logger()
|
||||
|
||||
ctx := IntoCtx(context.Background(), l)
|
||||
got := FromCtx(ctx)
|
||||
got.Info().Msg("hello")
|
||||
|
||||
var parsed map[string]any
|
||||
line := strings.TrimSpace(buf.String())
|
||||
if err := json.Unmarshal([]byte(line), &parsed); err != nil {
|
||||
t.Fatalf("not JSON: %v — %s", err, line)
|
||||
}
|
||||
if parsed["request_id"] != "req-1" {
|
||||
t.Errorf("request_id = %v, want req-1", parsed["request_id"])
|
||||
}
|
||||
if parsed["message"] != "hello" {
|
||||
t.Errorf("message = %v, want hello", parsed["message"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestFromCtx_NoLoggerFallsBackToDisabled(t *testing.T) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
t.Fatalf("FromCtx panicked: %v", r)
|
||||
}
|
||||
}()
|
||||
l := FromCtx(context.Background())
|
||||
l.Info().Msg("should not panic")
|
||||
}
|
||||
Reference in New Issue
Block a user