package logging import ( "context" "log/slog" ) type contextKey string // RequestIDKey is the context key for the request ID value. const RequestIDKey contextKey = "req_id" // contextHandler wraps a slog.Handler, extracting req_id from the // context.Context and appending it to every log record. type contextHandler struct { underlying slog.Handler } // NewContextHandler wraps an slog.Handler so that records get a req_id // attribute extracted from context.Context (if present). func NewContextHandler(h slog.Handler) slog.Handler { return &contextHandler{underlying: h} } func (h *contextHandler) Enabled(ctx context.Context, level slog.Level) bool { return h.underlying.Enabled(ctx, level) } func (h *contextHandler) Handle(ctx context.Context, r slog.Record) error { if reqID, ok := ctx.Value(RequestIDKey).(string); ok && reqID != "" { r.AddAttrs(slog.String("req_id", reqID)) } return h.underlying.Handle(ctx, r) } func (h *contextHandler) WithAttrs(attrs []slog.Attr) slog.Handler { return &contextHandler{underlying: h.underlying.WithAttrs(attrs)} } func (h *contextHandler) WithGroup(name string) slog.Handler { return &contextHandler{underlying: h.underlying.WithGroup(name)} } // WithRequestID returns a child context carrying a request ID. func WithRequestID(ctx context.Context, id string) context.Context { return context.WithValue(ctx, RequestIDKey, id) }