Skip to content

Commit d285439

Browse files
rxdcxdrninejchrys
authored andcommitted
Add Metrics Configuration Support to enable TcpClient metrics
1 parent 9d9e763 commit d285439

File tree

6 files changed

+81
-8
lines changed

6 files changed

+81
-8
lines changed

r2dbc-mysql/src/main/java/io/asyncer/r2dbc/mysql/MySqlConnectionConfiguration.java

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import io.netty.resolver.AddressResolverGroup;
2626
import org.jetbrains.annotations.Nullable;
2727
import org.reactivestreams.Publisher;
28+
import reactor.netty.internal.util.Metrics;
2829
import reactor.netty.resources.LoopResources;
2930
import reactor.netty.tcp.TcpResources;
3031

@@ -131,6 +132,8 @@ public final class MySqlConnectionConfiguration {
131132
@Nullable
132133
private final AddressResolverGroup<?> resolver;
133134

135+
private final boolean metrics;
136+
134137
private MySqlConnectionConfiguration(
135138
boolean isHost, String domain, int port, MySqlSslConfiguration ssl,
136139
boolean tcpKeepAlive, boolean tcpNoDelay, @Nullable Duration connectTimeout,
@@ -146,7 +149,8 @@ private MySqlConnectionConfiguration(
146149
Set<CompressionAlgorithm> compressionAlgorithms, int zstdCompressionLevel,
147150
@Nullable LoopResources loopResources,
148151
Extensions extensions, @Nullable Publisher<String> passwordPublisher,
149-
@Nullable AddressResolverGroup<?> resolver
152+
@Nullable AddressResolverGroup<?> resolver,
153+
boolean metrics
150154
) {
151155
this.isHost = isHost;
152156
this.domain = domain;
@@ -177,6 +181,7 @@ private MySqlConnectionConfiguration(
177181
this.extensions = extensions;
178182
this.passwordPublisher = passwordPublisher;
179183
this.resolver = resolver;
184+
this.metrics = metrics;
180185
}
181186

182187
/**
@@ -312,6 +317,10 @@ AddressResolverGroup<?> getResolver() {
312317
return resolver;
313318
}
314319

320+
boolean isMetrics() {
321+
return metrics;
322+
}
323+
315324
@Override
316325
public boolean equals(Object o) {
317326
if (this == o) {
@@ -349,7 +358,8 @@ public boolean equals(Object o) {
349358
Objects.equals(loopResources, that.loopResources) &&
350359
extensions.equals(that.extensions) &&
351360
Objects.equals(passwordPublisher, that.passwordPublisher) &&
352-
Objects.equals(resolver, that.resolver);
361+
Objects.equals(resolver, that.resolver) &&
362+
metrics == that.metrics;
353363
}
354364

355365
@Override
@@ -364,7 +374,7 @@ public int hashCode() {
364374
loadLocalInfilePath, localInfileBufferSize,
365375
queryCacheSize, prepareCacheSize,
366376
compressionAlgorithms, zstdCompressionLevel,
367-
loopResources, extensions, passwordPublisher, resolver);
377+
loopResources, extensions, passwordPublisher, resolver, metrics);
368378
}
369379

370380
@Override
@@ -398,7 +408,8 @@ private String buildCommonToStringPart() {
398408
", loopResources=" + loopResources +
399409
", extensions=" + extensions +
400410
", passwordPublisher=" + passwordPublisher +
401-
", resolver=" + resolver;
411+
", resolver=" + resolver +
412+
", metrics=" + metrics;
402413
}
403414

404415
/**
@@ -498,6 +509,8 @@ public static final class Builder {
498509
@Nullable
499510
private AddressResolverGroup<?> resolver;
500511

512+
private boolean metrics;
513+
501514
/**
502515
* Builds an immutable {@link MySqlConnectionConfiguration} with current options.
503516
*
@@ -532,7 +545,7 @@ public MySqlConnectionConfiguration build() {
532545
loadLocalInfilePath,
533546
localInfileBufferSize, queryCacheSize, prepareCacheSize,
534547
compressionAlgorithms, zstdCompressionLevel, loopResources,
535-
Extensions.from(extensions, autodetectExtensions), passwordPublisher, resolver);
548+
Extensions.from(extensions, autodetectExtensions), passwordPublisher, resolver, metrics);
536549
}
537550

538551
/**
@@ -1175,6 +1188,25 @@ public Builder resolver(AddressResolverGroup<?> resolver) {
11751188
return this;
11761189
}
11771190

1191+
/**
1192+
* Option to enable metrics to be collected and registered in Micrometer's globalRegistry
1193+
* with {@link reactor.netty.tcp.TcpClient#metrics(boolean)}. Defaults to {@code false}.
1194+
* <p>
1195+
* Note: It is required to add {@code io.micrometer.micrometer-core} dependency to classpath.
1196+
*
1197+
* @param enabled enable metrics for {@link reactor.netty.tcp.TcpClient}.
1198+
* @return this {@link Builder}
1199+
* @throws IllegalArgumentException if {@code io.micrometer:micrometer-core} is not on the classpath.
1200+
* @since 1.3.2
1201+
*/
1202+
public Builder metrics(boolean enabled) {
1203+
require(!enabled || Metrics.isMicrometerAvailable(),
1204+
"dependency `io.micrometer:micrometer-core` must be added to classpath if metrics enabled"
1205+
);
1206+
this.metrics = enabled;
1207+
return this;
1208+
}
1209+
11781210
private SslMode requireSslMode() {
11791211
SslMode sslMode = this.sslMode;
11801212

r2dbc-mysql/src/main/java/io/asyncer/r2dbc/mysql/MySqlConnectionFactory.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ private static Mono<MySqlConnection> getMySqlConnection(
148148
context,
149149
configuration.getConnectTimeout(),
150150
configuration.getLoopResources(),
151-
configuration.getResolver()
151+
configuration.getResolver(),
152+
configuration.isMetrics()
152153
)).flatMap(client -> {
153154
// Lazy init database after handshake/login
154155
boolean deferDatabase = configuration.isCreateDatabaseIfNotExist();

r2dbc-mysql/src/main/java/io/asyncer/r2dbc/mysql/MySqlConnectionFactoryProvider.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,16 @@ public final class MySqlConnectionFactoryProvider implements ConnectionFactoryPr
320320
*/
321321
public static final Option<AddressResolverGroup<?>> RESOLVER = Option.valueOf("resolver");
322322

323+
/**
324+
* Option to enable metrics to be collected and registered in Micrometer's globalRegistry
325+
* with {@link reactor.netty.tcp.TcpClient#metrics(boolean)}. Defaults to {@code false}.
326+
* <p>
327+
* Note: It is required to add {@code io.micrometer.micrometer-core} dependency to classpath.
328+
*
329+
* @since 1.3.2
330+
*/
331+
public static final Option<Boolean> METRICS = Option.valueOf("metrics");
332+
323333
@Override
324334
public ConnectionFactory create(ConnectionFactoryOptions options) {
325335
requireNonNull(options, "connectionFactoryOptions must not be null");
@@ -413,6 +423,8 @@ static MySqlConnectionConfiguration setup(ConnectionFactoryOptions options) {
413423
.to(builder::lockWaitTimeout);
414424
mapper.optional(STATEMENT_TIMEOUT).as(Duration.class, Duration::parse)
415425
.to(builder::statementTimeout);
426+
mapper.optional(METRICS).asBoolean()
427+
.to(builder::metrics);
416428

417429
return builder.build();
418430
}

r2dbc-mysql/src/main/java/io/asyncer/r2dbc/mysql/client/Client.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,19 +127,21 @@ public interface Client {
127127
* @param context the connection context
128128
* @param connectTimeout connect timeout, or {@code null} if it has no timeout
129129
* @param loopResources the loop resources to use
130+
* @param metrics if enable the {@link TcpClient#metrics)}
130131
* @return A {@link Mono} that will emit a connected {@link Client}.
131132
* @throws IllegalArgumentException if {@code ssl}, {@code address} or {@code context} is {@code null}.
132133
* @throws ArithmeticException if {@code connectTimeout} milliseconds overflow as an int
133134
*/
134135
static Mono<Client> connect(MySqlSslConfiguration ssl, SocketAddress address, boolean tcpKeepAlive,
135136
boolean tcpNoDelay, ConnectionContext context, @Nullable Duration connectTimeout,
136-
LoopResources loopResources, @Nullable AddressResolverGroup<?> resolver) {
137+
LoopResources loopResources, @Nullable AddressResolverGroup<?> resolver, boolean metrics) {
137138
requireNonNull(ssl, "ssl must not be null");
138139
requireNonNull(address, "address must not be null");
139140
requireNonNull(context, "context must not be null");
140141

141142
TcpClient tcpClient = TcpClient.newConnection()
142-
.runOn(loopResources);
143+
.runOn(loopResources)
144+
.metrics(metrics);
143145

144146
if (connectTimeout != null) {
145147
tcpClient = tcpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS,

r2dbc-mysql/src/test/java/io/asyncer/r2dbc/mysql/MySqlConnectionConfigurationTest.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,19 @@ void validResolver() {
222222
assertThat(resolverGroup).isSameAs(resolver);
223223
}
224224

225+
@Test
226+
void invalidMetrics() {
227+
// throw exception when metrics true without micrometer-core dependency
228+
assertThatIllegalArgumentException().isThrownBy(() ->
229+
MySqlConnectionConfiguration
230+
.builder()
231+
.host(HOST)
232+
.user(USER)
233+
.metrics(true)
234+
.build()
235+
);
236+
}
237+
225238
private static MySqlConnectionConfiguration unixSocketSslMode(SslMode sslMode) {
226239
return MySqlConnectionConfiguration.builder()
227240
.unixSocket(UNIX_SOCKET)

r2dbc-mysql/src/test/java/io/asyncer/r2dbc/mysql/MySqlConnectionFactoryProviderTest.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import java.util.stream.Collectors;
5252
import java.util.stream.Stream;
5353

54+
import static io.asyncer.r2dbc.mysql.MySqlConnectionFactoryProvider.METRICS;
5455
import static io.asyncer.r2dbc.mysql.MySqlConnectionFactoryProvider.PASSWORD_PUBLISHER;
5556
import static io.asyncer.r2dbc.mysql.MySqlConnectionFactoryProvider.RESOLVER;
5657
import static io.asyncer.r2dbc.mysql.MySqlConnectionFactoryProvider.USE_SERVER_PREPARE_STATEMENT;
@@ -469,6 +470,18 @@ void validResolver() {
469470
assertThat(ConnectionFactories.get(options)).isExactlyInstanceOf(MySqlConnectionFactory.class);
470471
}
471472

473+
@Test
474+
void invalidMetrics() {
475+
// throw exception when metrics true without micrometer-core dependency
476+
assertThatIllegalArgumentException().isThrownBy(() ->
477+
ConnectionFactories.get(ConnectionFactoryOptions.builder()
478+
.option(DRIVER, "mysql")
479+
.option(HOST, "127.0.0.1")
480+
.option(USER, "root")
481+
.option(METRICS, true)
482+
.build()));
483+
}
484+
472485
@Test
473486
void allConfigurationOptions() {
474487
List<String> exceptConfigs = Arrays.asList(

0 commit comments

Comments
 (0)