Skip to content

Commit 94dfdff

Browse files
authored
GODRIVER-2910 Add durations to connection pool events. (#1590)
1 parent b693b75 commit 94dfdff

File tree

7 files changed

+181
-26
lines changed

7 files changed

+181
-26
lines changed

event/monitoring.go

+1
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ type PoolEvent struct {
117117
Address string `json:"address"`
118118
ConnectionID uint64 `json:"connectionId"`
119119
PoolOptions *MonitorPoolOptions `json:"options"`
120+
Duration time.Duration `json:"duration"`
120121
Reason string `json:"reason"`
121122
// ServiceID is only set if the Type is PoolCleared and the server is deployed behind a load balancer. This field
122123
// can be used to distinguish between individual servers in a load balanced deployment.

testdata/connection-monitoring-and-pooling/logging/connection-logging.json

+30-2
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,13 @@
140140
"int",
141141
"long"
142142
]
143+
},
144+
"durationMS": {
145+
"$$type": [
146+
"double",
147+
"int",
148+
"long"
149+
]
143150
}
144151
}
145152
},
@@ -162,6 +169,13 @@
162169
"int",
163170
"long"
164171
]
172+
},
173+
"durationMS": {
174+
"$$type": [
175+
"double",
176+
"int",
177+
"long"
178+
]
165179
}
166180
}
167181
},
@@ -222,6 +236,13 @@
222236
"int",
223237
"long"
224238
]
239+
},
240+
"durationMS": {
241+
"$$type": [
242+
"double",
243+
"int",
244+
"long"
245+
]
225246
}
226247
}
227248
},
@@ -444,7 +465,7 @@
444465
{
445466
"level": "debug",
446467
"component": "connection",
447-
"unordered": true,
468+
"unordered": true,
448469
"data": {
449470
"message": "Connection closed",
450471
"driverConnectionId": {
@@ -471,7 +492,7 @@
471492
{
472493
"level": "debug",
473494
"component": "connection",
474-
"unordered": true,
495+
"unordered": true,
475496
"data": {
476497
"message": "Connection checkout failed",
477498
"serverHost": {
@@ -486,6 +507,13 @@
486507
"reason": "An error occurred while trying to establish a new connection",
487508
"error": {
488509
"$$exists": true
510+
},
511+
"durationMS": {
512+
"$$type": [
513+
"double",
514+
"int",
515+
"long"
516+
]
489517
}
490518
}
491519
}

testdata/connection-monitoring-and-pooling/logging/connection-logging.yml

+4
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ tests:
6666
driverConnectionId: { $$type: [int, long] }
6767
serverHost: { $$type: string }
6868
serverPort: { $$type: [int, long] }
69+
durationMS: { $$type: [double, int, long] }
6970

7071
- level: debug
7172
component: connection
@@ -74,6 +75,7 @@ tests:
7475
driverConnectionId: { $$type: [int, long] }
7576
serverHost: { $$type: string }
7677
serverPort: { $$type: [int, long] }
78+
durationMS: { $$type: [double, int, long] }
7779

7880
- level: debug
7981
component: connection
@@ -98,6 +100,7 @@ tests:
98100
driverConnectionId: { $$type: [int, long] }
99101
serverHost: { $$type: string }
100102
serverPort: { $$type: [int, long] }
103+
durationMS: { $$type: [double, int, long] }
101104

102105
- level: debug
103106
component: connection
@@ -219,4 +222,5 @@ tests:
219222
serverPort: { $$type: [int, long] }
220223
reason: "An error occurred while trying to establish a new connection"
221224
error: { $$exists: true }
225+
durationMS: { $$type: [double, int, long] }
222226
unordered: true

testdata/connection-monitoring-and-pooling/logging/connection-pool-options.json

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"description": "connection-pool-logging",
2+
"description": "connection-pool-options",
33
"schemaVersion": "1.13",
44
"runOnRequirements": [
55
{
@@ -128,6 +128,13 @@
128128
"int",
129129
"long"
130130
]
131+
},
132+
"durationMS": {
133+
"$$type": [
134+
"double",
135+
"int",
136+
"long"
137+
]
131138
}
132139
}
133140
}

testdata/connection-monitoring-and-pooling/logging/connection-pool-options.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
description: "connection-pool-logging"
1+
description: "connection-pool-options"
22

33
schemaVersion: "1.13"
44

@@ -71,6 +71,7 @@ tests:
7171
driverConnectionId: { $$type: [int, long] }
7272
serverHost: { $$type: string }
7373
serverPort: { $$type: [int, long] }
74+
durationMS: { $$type: [double, int, long] }
7475

7576
# Drivers who have not done DRIVERS-1943 will need to skip this test.
7677
- description: "maxConnecting should be included in connection pool created message when specified"

x/mongo/driver/topology/pool.go

+48-22
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,7 @@ func (p *pool) checkOut(ctx context.Context) (conn *connection, err error) {
467467
})
468468
}
469469

470+
start := time.Now()
470471
// Check the pool state while holding a stateMu read lock. If the pool state is not "ready",
471472
// return an error. Do all of this while holding the stateMu read lock to prevent a state change between
472473
// checking the state and entering the wait queue. Not holding the stateMu read lock here may
@@ -477,8 +478,10 @@ func (p *pool) checkOut(ctx context.Context) (conn *connection, err error) {
477478
case poolClosed:
478479
p.stateMu.RUnlock()
479480

481+
duration := time.Since(start)
480482
if mustLogPoolMessage(p) {
481483
keysAndValues := logger.KeyValues{
484+
logger.KeyDurationMS, duration.Milliseconds(),
482485
logger.KeyReason, logger.ReasonConnCheckoutFailedPoolClosed,
483486
}
484487

@@ -487,18 +490,21 @@ func (p *pool) checkOut(ctx context.Context) (conn *connection, err error) {
487490

488491
if p.monitor != nil {
489492
p.monitor.Event(&event.PoolEvent{
490-
Type: event.GetFailed,
491-
Address: p.address.String(),
492-
Reason: event.ReasonPoolClosed,
493+
Type: event.GetFailed,
494+
Address: p.address.String(),
495+
Duration: duration,
496+
Reason: event.ReasonPoolClosed,
493497
})
494498
}
495499
return nil, ErrPoolClosed
496500
case poolPaused:
497501
err := poolClearedError{err: p.lastClearErr, address: p.address}
498502
p.stateMu.RUnlock()
499503

504+
duration := time.Since(start)
500505
if mustLogPoolMessage(p) {
501506
keysAndValues := logger.KeyValues{
507+
logger.KeyDurationMS, duration.Milliseconds(),
502508
logger.KeyReason, logger.ReasonConnCheckoutFailedError,
503509
}
504510

@@ -507,10 +513,11 @@ func (p *pool) checkOut(ctx context.Context) (conn *connection, err error) {
507513

508514
if p.monitor != nil {
509515
p.monitor.Event(&event.PoolEvent{
510-
Type: event.GetFailed,
511-
Address: p.address.String(),
512-
Reason: event.ReasonConnectionErrored,
513-
Error: err,
516+
Type: event.GetFailed,
517+
Address: p.address.String(),
518+
Duration: duration,
519+
Reason: event.ReasonConnectionErrored,
520+
Error: err,
514521
})
515522
}
516523
return nil, err
@@ -539,9 +546,11 @@ func (p *pool) checkOut(ctx context.Context) (conn *connection, err error) {
539546
// or an error, so unlock the stateMu lock here.
540547
p.stateMu.RUnlock()
541548

549+
duration := time.Since(start)
542550
if w.err != nil {
543551
if mustLogPoolMessage(p) {
544552
keysAndValues := logger.KeyValues{
553+
logger.KeyDurationMS, duration.Milliseconds(),
545554
logger.KeyReason, logger.ReasonConnCheckoutFailedError,
546555
}
547556

@@ -550,18 +559,21 @@ func (p *pool) checkOut(ctx context.Context) (conn *connection, err error) {
550559

551560
if p.monitor != nil {
552561
p.monitor.Event(&event.PoolEvent{
553-
Type: event.GetFailed,
554-
Address: p.address.String(),
555-
Reason: event.ReasonConnectionErrored,
556-
Error: w.err,
562+
Type: event.GetFailed,
563+
Address: p.address.String(),
564+
Duration: duration,
565+
Reason: event.ReasonConnectionErrored,
566+
Error: w.err,
557567
})
558568
}
559569
return nil, w.err
560570
}
561571

572+
duration = time.Since(start)
562573
if mustLogPoolMessage(p) {
563574
keysAndValues := logger.KeyValues{
564575
logger.KeyDriverConnectionID, w.conn.driverConnectionID,
576+
logger.KeyDurationMS, duration.Milliseconds(),
565577
}
566578

567579
logPoolMessage(p, logger.ConnectionCheckedOut, keysAndValues...)
@@ -572,6 +584,7 @@ func (p *pool) checkOut(ctx context.Context) (conn *connection, err error) {
572584
Type: event.GetSucceeded,
573585
Address: p.address.String(),
574586
ConnectionID: w.conn.driverConnectionID,
587+
Duration: duration,
575588
})
576589
}
577590

@@ -584,12 +597,14 @@ func (p *pool) checkOut(ctx context.Context) (conn *connection, err error) {
584597
p.stateMu.RUnlock()
585598

586599
// Wait for either the wantConn to be ready or for the Context to time out.
587-
start := time.Now()
600+
waitQueueStart := time.Now()
588601
select {
589602
case <-w.ready:
590603
if w.err != nil {
604+
duration := time.Since(start)
591605
if mustLogPoolMessage(p) {
592606
keysAndValues := logger.KeyValues{
607+
logger.KeyDurationMS, duration.Milliseconds(),
593608
logger.KeyReason, logger.ReasonConnCheckoutFailedError,
594609
logger.KeyError, w.err.Error(),
595610
}
@@ -599,19 +614,22 @@ func (p *pool) checkOut(ctx context.Context) (conn *connection, err error) {
599614

600615
if p.monitor != nil {
601616
p.monitor.Event(&event.PoolEvent{
602-
Type: event.GetFailed,
603-
Address: p.address.String(),
604-
Reason: event.ReasonConnectionErrored,
605-
Error: w.err,
617+
Type: event.GetFailed,
618+
Address: p.address.String(),
619+
Duration: duration,
620+
Reason: event.ReasonConnectionErrored,
621+
Error: w.err,
606622
})
607623
}
608624

609625
return nil, w.err
610626
}
611627

628+
duration := time.Since(start)
612629
if mustLogPoolMessage(p) {
613630
keysAndValues := logger.KeyValues{
614631
logger.KeyDriverConnectionID, w.conn.driverConnectionID,
632+
logger.KeyDurationMS, duration.Milliseconds(),
615633
}
616634

617635
logPoolMessage(p, logger.ConnectionCheckedOut, keysAndValues...)
@@ -622,14 +640,17 @@ func (p *pool) checkOut(ctx context.Context) (conn *connection, err error) {
622640
Type: event.GetSucceeded,
623641
Address: p.address.String(),
624642
ConnectionID: w.conn.driverConnectionID,
643+
Duration: duration,
625644
})
626645
}
627646
return w.conn, nil
628647
case <-ctx.Done():
629-
duration := time.Since(start)
648+
waitQueueDuration := time.Since(waitQueueStart)
630649

650+
duration := time.Since(start)
631651
if mustLogPoolMessage(p) {
632652
keysAndValues := logger.KeyValues{
653+
logger.KeyDurationMS, duration.Milliseconds(),
633654
logger.KeyReason, logger.ReasonConnCheckoutFailedTimout,
634655
}
635656

@@ -638,10 +659,11 @@ func (p *pool) checkOut(ctx context.Context) (conn *connection, err error) {
638659

639660
if p.monitor != nil {
640661
p.monitor.Event(&event.PoolEvent{
641-
Type: event.GetFailed,
642-
Address: p.address.String(),
643-
Reason: event.ReasonTimedOut,
644-
Error: ctx.Err(),
662+
Type: event.GetFailed,
663+
Address: p.address.String(),
664+
Duration: duration,
665+
Reason: event.ReasonTimedOut,
666+
Error: ctx.Err(),
645667
})
646668
}
647669

@@ -650,7 +672,7 @@ func (p *pool) checkOut(ctx context.Context) (conn *connection, err error) {
650672
maxPoolSize: p.maxSize,
651673
totalConnections: p.totalConnectionCount(),
652674
availableConnections: p.availableConnectionCount(),
653-
waitDuration: duration,
675+
waitDuration: waitQueueDuration,
654676
}
655677
if p.loadBalanced {
656678
err.pinnedConnections = &pinnedConnections{
@@ -1085,6 +1107,7 @@ func (p *pool) createConnections(ctx context.Context, wg *sync.WaitGroup) {
10851107
})
10861108
}
10871109

1110+
start := time.Now()
10881111
// Pass the createConnections context to connect to allow pool close to cancel connection
10891112
// establishment so shutdown doesn't block indefinitely if connectTimeout=0.
10901113
err := conn.connect(ctx)
@@ -1111,9 +1134,11 @@ func (p *pool) createConnections(ctx context.Context, wg *sync.WaitGroup) {
11111134
continue
11121135
}
11131136

1137+
duration := time.Since(start)
11141138
if mustLogPoolMessage(p) {
11151139
keysAndValues := logger.KeyValues{
11161140
logger.KeyDriverConnectionID, conn.driverConnectionID,
1141+
logger.KeyDurationMS, duration.Milliseconds(),
11171142
}
11181143

11191144
logPoolMessage(p, logger.ConnectionReady, keysAndValues...)
@@ -1124,6 +1149,7 @@ func (p *pool) createConnections(ctx context.Context, wg *sync.WaitGroup) {
11241149
Type: event.ConnectionReady,
11251150
Address: p.address.String(),
11261151
ConnectionID: conn.driverConnectionID,
1152+
Duration: duration,
11271153
})
11281154
}
11291155

0 commit comments

Comments
 (0)