@@ -11,6 +11,7 @@ import (
1111 "github.com/redis/go-redis/v9/internal"
1212 "github.com/redis/go-redis/v9/internal/proto"
1313 "github.com/redis/go-redis/v9/internal/util"
14+ "github.com/redis/go-redis/v9/logging"
1415)
1516
1617var (
@@ -119,6 +120,9 @@ type Options struct {
119120 // DialerRetryTimeout is the backoff duration between retry attempts.
120121 // Default: 100ms
121122 DialerRetryTimeout time.Duration
123+
124+ // Optional logger for connection pool operations.
125+ Logger logging.LoggerWithLevelI
122126}
123127
124128type lastDialErrorWrap struct {
@@ -254,7 +258,7 @@ func (p *ConnPool) checkMinIdleConns() {
254258 p .idleConnsLen .Add (- 1 )
255259
256260 p .freeTurn ()
257- internal . Logger . Printf (context .Background (), "addIdleConn panic: %+v" , err )
261+ p . logger (). Errorf (context .Background (), "addIdleConn panic: %+v" , err )
258262 }
259263 }()
260264
@@ -416,7 +420,7 @@ func (p *ConnPool) dialConn(ctx context.Context, pooled bool) (*Conn, error) {
416420 return cn , nil
417421 }
418422
419- internal . Logger . Printf (ctx , "redis: connection pool: failed to dial after %d attempts: %v" , attempt , lastErr )
423+ p . logger (). Errorf (ctx , "redis: connection pool: failed to dial after %d attempts: %v" , attempt , lastErr )
420424 // All retries failed - handle error tracking
421425 p .setLastDialError (lastErr )
422426 if atomic .AddUint32 (& p .dialErrorsNum , 1 ) == uint32 (p .cfg .PoolSize ) {
@@ -510,10 +514,10 @@ func (p *ConnPool) getConn(ctx context.Context) (*Conn, error) {
510514 acceptConn , err := hookManager .ProcessOnGet (ctx , cn , false )
511515 if err != nil || ! acceptConn {
512516 if err != nil {
513- internal . Logger . Printf (ctx , "redis: connection pool: failed to process idle connection by hook: %v" , err )
517+ p . logger (). Errorf (ctx , "redis: connection pool: failed to process idle connection by hook: %v" , err )
514518 _ = p .CloseConn (cn )
515519 } else {
516- internal . Logger . Printf (ctx , "redis: connection pool: conn[%d] rejected by hook, returning to pool" , cn .GetID ())
520+ p . logger (). Errorf (ctx , "redis: connection pool: conn[%d] rejected by hook, returning to pool" , cn .GetID ())
517521 // Return connection to pool without freeing the turn that this Get() call holds.
518522 // We use putConnWithoutTurn() to run all the Put hooks and logic without freeing a turn.
519523 p .putConnWithoutTurn (ctx , cn )
@@ -541,7 +545,7 @@ func (p *ConnPool) getConn(ctx context.Context) (*Conn, error) {
541545 // this should not happen with a new connection, but we handle it gracefully
542546 if err != nil || ! acceptConn {
543547 // Failed to process connection, discard it
544- internal . Logger . Printf (ctx , "redis: connection pool: failed to process new connection conn[%d] by hook: accept=%v, err=%v" , newcn .GetID (), acceptConn , err )
548+ p . logger (). Errorf (ctx , "redis: connection pool: failed to process new connection conn[%d] by hook: accept=%v, err=%v" , newcn .GetID (), acceptConn , err )
545549 _ = p .CloseConn (newcn )
546550 return nil , err
547551 }
@@ -583,7 +587,7 @@ func (p *ConnPool) queuedNewConn(ctx context.Context) (*Conn, error) {
583587 if ! freeTurnCalled {
584588 p .freeTurn ()
585589 }
586- internal . Logger . Printf ( context . Background () , "queuedNewConn panic: %+v" , err )
590+ p . logger (). Errorf ( ctx , "queuedNewConn panic: %+v" , err )
587591 }
588592 }()
589593
@@ -736,7 +740,7 @@ func (p *ConnPool) popIdle() (*Conn, error) {
736740
737741 // If we exhausted all attempts without finding a usable connection, return nil
738742 if attempts > 1 && attempts >= maxAttempts && int32 (attempts ) >= p .poolSize .Load () {
739- internal . Logger . Printf (context .Background (), "redis: connection pool: failed to get a usable connection after %d attempts" , attempts )
743+ p . logger (). Errorf (context .Background (), "redis: connection pool: failed to get a usable connection after %d attempts" , attempts )
740744 return nil , nil
741745 }
742746
@@ -765,7 +769,7 @@ func (p *ConnPool) putConn(ctx context.Context, cn *Conn, freeTurn bool) {
765769 // Peek at the reply type to check if it's a push notification
766770 if replyType , err := cn .PeekReplyTypeSafe (); err != nil || replyType != proto .RespPush {
767771 // Not a push notification or error peeking, remove connection
768- internal . Logger . Printf (ctx , "Conn has unread data (not push notification), removing it" )
772+ p . logger (). Errorf (ctx , "Conn has unread data (not push notification), removing it" )
769773 p .removeConnInternal (ctx , cn , err , freeTurn )
770774 return
771775 }
@@ -778,7 +782,7 @@ func (p *ConnPool) putConn(ctx context.Context, cn *Conn, freeTurn bool) {
778782 if hookManager != nil {
779783 shouldPool , shouldRemove , err = hookManager .ProcessOnPut (ctx , cn )
780784 if err != nil {
781- internal . Logger . Printf (ctx , "Connection hook error: %v" , err )
785+ p . logger (). Errorf (ctx , "Connection hook error: %v" , err )
782786 p .removeConnInternal (ctx , cn , err , freeTurn )
783787 return
784788 }
@@ -811,12 +815,12 @@ func (p *ConnPool) putConn(ctx context.Context, cn *Conn, freeTurn bool) {
811815 case StateUnusable :
812816 // expected state, don't log it
813817 case StateClosed :
814- internal . Logger . Printf (ctx , "Unexpected conn[%d] state changed by hook to %v, closing it" , cn .GetID (), currentState )
818+ p . logger (). Errorf (ctx , "Unexpected conn[%d] state changed by hook to %v, closing it" , cn .GetID (), currentState )
815819 shouldCloseConn = true
816820 p .removeConnWithLock (cn )
817821 default :
818822 // Pool as-is
819- internal . Logger . Printf (ctx , "Unexpected conn[%d] state changed by hook to %v, pooling as-is" , cn .GetID (), currentState )
823+ p . logger (). Warnf (ctx , "Unexpected conn[%d] state changed by hook to %v, pooling as-is" , cn .GetID (), currentState )
820824 }
821825 }
822826
@@ -1030,7 +1034,7 @@ func (p *ConnPool) isHealthyConn(cn *Conn, nowNs int64) bool {
10301034 if replyType , err := cn .rd .PeekReplyType (); err == nil && replyType == proto .RespPush {
10311035 // For RESP3 connections with push notifications, we allow some buffered data
10321036 // The client will process these notifications before using the connection
1033- internal . Logger . Printf (
1037+ p . logger (). Infof (
10341038 context .Background (),
10351039 "push: conn[%d] has buffered data, likely push notifications - will be processed by client" ,
10361040 cn .GetID (),
@@ -1053,3 +1057,10 @@ func (p *ConnPool) isHealthyConn(cn *Conn, nowNs int64) bool {
10531057 cn .SetUsedAtNs (nowNs )
10541058 return true
10551059}
1060+
1061+ func (p * ConnPool ) logger () * logging.LoggerWrapper {
1062+ if p .cfg != nil && p .cfg .Logger != nil {
1063+ return logging .NewLoggerWrapper (p .cfg .Logger )
1064+ }
1065+ return logging .LoggerWithLevel ()
1066+ }
0 commit comments