From f39c5e058e11342414b8ba60699b61699b0a084e Mon Sep 17 00:00:00 2001 From: Andrei Aaron Date: Fri, 19 Dec 2025 07:32:13 +0200 Subject: [PATCH] fix: make sure the function and caller information are added to log messages emitted by 3rd party libraries using slog directly. (#3659) --- pkg/log/log.go | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/pkg/log/log.go b/pkg/log/log.go index d64dbf19..94d63e54 100644 --- a/pkg/log/log.go +++ b/pkg/log/log.go @@ -378,6 +378,8 @@ func GoroutineID() int { } // CallerHandler adds caller information to log records. +// This handler captures caller information for all log records, including those +// from external libraries like regclient that use native slog.Logger. type CallerHandler struct { handler slog.Handler } @@ -387,8 +389,32 @@ func (h *CallerHandler) Enabled(ctx context.Context, level slog.Level) bool { } func (h *CallerHandler) Handle(ctx context.Context, record slog.Record) error { - // Caller information is now added directly in Event.Msg/Msgf methods - // This handler is kept for compatibility but no longer modifies the record + // Only add caller info if not already present (to avoid duplicating info from Event.Msg/Msgf) + hasCallerAttr := false + record.Attrs(func(attr slog.Attr) bool { + if attr.Key == "caller" { + hasCallerAttr = true + + return false // stop iteration + } + + return true + }) + + if !hasCallerAttr { + // This is where we extract caller info in case the 3rd party library uses slog directly. + // Get caller information from the PC in the record + fs := runtime.CallersFrames([]uintptr{record.PC}) + f, _ := fs.Next() + + if f.File != "" { + record.AddAttrs( + slog.String("caller", fmt.Sprintf("%s:%d", f.File, f.Line)), + slog.String("func", f.Function), + ) + } + } + return h.handler.Handle(ctx, record) }