// Package pgxslog implements [tracelog.Logger] adapter for [slog.Handler].
package pgxslog import ( ) var _ tracelog.Logger = (*Logger)(nil) // Logger is an adapter from [slog.Handler] to [tracelog.Logger]. type Logger struct { handler slog.Handler timeNow func() time.Time } // NewLogger return a new [Logger] instance. func ( slog.Handler, func() time.Time) *Logger { return &Logger{ handler: , timeNow: , } } // Log implements the [tracelog.Logger] interface. func ( *Logger) ( context.Context, tracelog.LogLevel, string, map[string]any, ) { := translateTraceLogLevel() if !.handler.Enabled(, ) { return } := make([]slog.Attr, 0, len()) for , := range { = append(, slog.Any(, )) } slices.SortFunc(, func(, slog.Attr) int { return cmp.Compare(.Key, .Key) }) // Skip 4 stack frames to log pgx.QueryTracer caller: // - runtime.Callers // - this function // - this function’s caller (TraceLog.log helper) // - QueryTracer hook var [1]uintptr runtime.Callers(4, [:]) := slog.NewRecord(.now(), , , [0]) .AddAttrs(...) _ = .handler.Handle(, ) } func ( *Logger) () time.Time { if .timeNow == nil { return time.Now() } return .timeNow() } func ( tracelog.LogLevel) slog.Level { switch { case tracelog.LogLevelTrace: return slog.LevelDebug - 1 case tracelog.LogLevelDebug: return slog.LevelDebug case tracelog.LogLevelInfo: return slog.LevelInfo case tracelog.LogLevelWarn: return slog.LevelWarn case tracelog.LogLevelError: return slog.LevelError } return 0 }