Skip to content

Commit 557d997

Browse files
Add counter of failed attempts to retrieve a connection from the pool (#5057)
* Add counter of failed attempts to retrieve a connection from the pool * Test counter of failed attempts to retrieve a connection from the pool
1 parent 1f20895 commit 557d997

File tree

2 files changed

+50
-4
lines changed

2 files changed

+50
-4
lines changed

micrometer-core/src/main/java/io/micrometer/core/instrument/binder/mongodb/MongoMetricsConnectionPoolListener.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import io.micrometer.common.lang.NonNullApi;
2222
import io.micrometer.common.lang.NonNullFields;
2323
import io.micrometer.core.annotation.Incubating;
24+
import io.micrometer.core.instrument.Counter;
2425
import io.micrometer.core.instrument.Gauge;
2526
import io.micrometer.core.instrument.Meter;
2627
import io.micrometer.core.instrument.MeterRegistry;
@@ -51,6 +52,8 @@ public class MongoMetricsConnectionPoolListener implements ConnectionPoolListene
5152

5253
private final Map<ServerId, AtomicInteger> checkedOutCounts = new ConcurrentHashMap<>();
5354

55+
private final Map<ServerId, Counter> checkOutFailedCounters = new ConcurrentHashMap<>();
56+
5457
private final Map<ServerId, AtomicInteger> waitQueueSizes = new ConcurrentHashMap<>();
5558

5659
private final Map<ServerId, List<Meter>> meters = new ConcurrentHashMap<>();
@@ -85,6 +88,8 @@ public void connectionPoolCreated(ConnectionPoolCreatedEvent event) {
8588
"the current size of the connection pool, including idle and and in-use members", poolSizes));
8689
connectionMeters.add(registerGauge(event, METRIC_PREFIX + "checkedout",
8790
"the count of connections that are currently in use", checkedOutCounts));
91+
connectionMeters.add(registerCounter(event, METRIC_PREFIX + "checkoutfailed",
92+
"the count of failed attempts to retrieve a connection", checkOutFailedCounters));
8893
connectionMeters.add(registerGauge(event, METRIC_PREFIX + "waitqueuesize",
8994
"the current size of the wait queue for a connection from the pool", waitQueueSizes));
9095
meters.put(event.getServerId(), connectionMeters);
@@ -99,6 +104,7 @@ public void connectionPoolClosed(ConnectionPoolClosedEvent event) {
99104
meters.remove(serverId);
100105
poolSizes.remove(serverId);
101106
checkedOutCounts.remove(serverId);
107+
checkOutFailedCounters.remove(serverId);
102108
waitQueueSizes.remove(serverId);
103109
}
104110

@@ -129,6 +135,11 @@ public void connectionCheckOutFailed(ConnectionCheckOutFailedEvent event) {
129135
if (waitQueueSize != null) {
130136
waitQueueSize.decrementAndGet();
131137
}
138+
139+
Counter checkOutFailedCounter = checkOutFailedCounters.get(event.getServerId());
140+
if (checkOutFailedCounter != null) {
141+
checkOutFailedCounter.increment();
142+
}
132143
}
133144

134145
@Override
@@ -165,4 +176,14 @@ private Gauge registerGauge(ConnectionPoolCreatedEvent event, String metricName,
165176
.register(registry);
166177
}
167178

179+
private Counter registerCounter(ConnectionPoolCreatedEvent event, String metricName, String description,
180+
Map<ServerId, Counter> metrics) {
181+
Counter counter = Counter.builder(metricName)
182+
.description(description)
183+
.tags(tagsProvider.connectionPoolTags(event))
184+
.register(registry);
185+
metrics.put(event.getServerId(), counter);
186+
return counter;
187+
}
188+
168189
}

micrometer-core/src/test/java/io/micrometer/core/instrument/binder/mongodb/MongoMetricsConnectionPoolListenerTest.java

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@
2424
import com.mongodb.connection.ConnectionPoolSettings;
2525
import com.mongodb.connection.ServerId;
2626
import com.mongodb.event.*;
27+
import io.micrometer.common.lang.NonNull;
2728
import io.micrometer.core.Issue;
2829
import io.micrometer.core.instrument.MeterRegistry;
2930
import io.micrometer.core.instrument.Tags;
3031
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
3132
import org.junit.jupiter.api.Test;
3233

34+
import java.util.concurrent.TimeUnit;
3335
import java.util.concurrent.atomic.AtomicReference;
3436

3537
import static java.util.Collections.singletonList;
@@ -55,7 +57,7 @@ void shouldCreatePoolMetrics() {
5557
.applyToClusterSettings(builder -> builder.hosts(singletonList(new ServerAddress(host, port)))
5658
.addClusterListener(new ClusterListener() {
5759
@Override
58-
public void clusterOpening(ClusterOpeningEvent event) {
60+
public void clusterOpening(@NonNull ClusterOpeningEvent event) {
5961
clusterId.set(event.getClusterId().getValue());
6062
}
6163
}))
@@ -91,7 +93,7 @@ void shouldCreatePoolMetricsWithCustomTags() {
9193
.applyToClusterSettings(builder -> builder.hosts(singletonList(new ServerAddress(host, port)))
9294
.addClusterListener(new ClusterListener() {
9395
@Override
94-
public void clusterOpening(ClusterOpeningEvent event) {
96+
public void clusterOpening(@NonNull ClusterOpeningEvent event) {
9597
clusterId.set(event.getClusterId().getValue());
9698
}
9799
}))
@@ -107,6 +109,7 @@ public void clusterOpening(ClusterOpeningEvent event) {
107109

108110
assertThat(registry.get("mongodb.driver.pool.size").tags(tags).gauge().value()).isEqualTo(2);
109111
assertThat(registry.get("mongodb.driver.pool.checkedout").gauge().value()).isZero();
112+
assertThat(registry.get("mongodb.driver.pool.checkoutfailed").counter().count()).isZero();
110113
assertThat(registry.get("mongodb.driver.pool.waitqueuesize").gauge().value()).isZero();
111114

112115
mongo.close();
@@ -117,6 +120,28 @@ public void clusterOpening(ClusterOpeningEvent event) {
117120
.isNull();
118121
}
119122

123+
@Test
124+
void shouldIncrementCheckoutFailedCount() {
125+
ServerId serverId = new ServerId(new ClusterId(), new ServerAddress(host, port));
126+
MongoMetricsConnectionPoolListener listener = new MongoMetricsConnectionPoolListener(registry);
127+
listener
128+
.connectionPoolCreated(new ConnectionPoolCreatedEvent(serverId, ConnectionPoolSettings.builder().build()));
129+
130+
// start a connection checkout
131+
listener.connectionCheckOutStarted(new ConnectionCheckOutStartedEvent(serverId, -1));
132+
assertThat(registry.get("mongodb.driver.pool.waitqueuesize").gauge().value()).isEqualTo(1);
133+
assertThat(registry.get("mongodb.driver.pool.checkoutfailed").counter().count()).isZero();
134+
135+
// let the connection checkout fail, simulating a timeout
136+
ConnectionCheckOutFailedEvent.Reason reason = ConnectionCheckOutFailedEvent.Reason.TIMEOUT;
137+
long elapsedTimeNanos = TimeUnit.SECONDS.toNanos(120);
138+
ConnectionCheckOutFailedEvent checkOutFailedEvent = new ConnectionCheckOutFailedEvent(serverId, -1, reason,
139+
elapsedTimeNanos);
140+
listener.connectionCheckOutFailed(checkOutFailedEvent);
141+
assertThat(registry.get("mongodb.driver.pool.waitqueuesize").gauge().value()).isZero();
142+
assertThat(registry.get("mongodb.driver.pool.checkoutfailed").counter().count()).isEqualTo(1);
143+
}
144+
120145
@Issue("#2384")
121146
@Test
122147
void whenConnectionCheckedInAfterPoolClose_thenNoExceptionThrown() {
@@ -125,9 +150,9 @@ void whenConnectionCheckedInAfterPoolClose_thenNoExceptionThrown() {
125150
MongoMetricsConnectionPoolListener listener = new MongoMetricsConnectionPoolListener(registry);
126151
listener
127152
.connectionPoolCreated(new ConnectionPoolCreatedEvent(serverId, ConnectionPoolSettings.builder().build()));
128-
listener.connectionCheckedOut(new ConnectionCheckedOutEvent(connectionId));
153+
listener.connectionCheckedOut(new ConnectionCheckedOutEvent(connectionId, -1, 0));
129154
listener.connectionPoolClosed(new ConnectionPoolClosedEvent(serverId));
130-
assertThatCode(() -> listener.connectionCheckedIn(new ConnectionCheckedInEvent(connectionId)))
155+
assertThatCode(() -> listener.connectionCheckedIn(new ConnectionCheckedInEvent(connectionId, -1)))
131156
.doesNotThrowAnyException();
132157
}
133158

0 commit comments

Comments
 (0)