Skip to content

Commit d8d09ed

Browse files
Add pool lease metrics and helpers for connection managers (#799)
1 parent ec0474c commit d8d09ed

15 files changed

+1189
-40
lines changed

httpclient5-observation/src/main/java/org/apache/hc/client5/http/observation/HttpClientObservationSupport.java

Lines changed: 116 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,24 @@
3333
import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder;
3434
import org.apache.hc.client5.http.impl.cache.CachingHttpAsyncClientBuilder;
3535
import org.apache.hc.client5.http.impl.cache.CachingHttpClientBuilder;
36+
import org.apache.hc.client5.http.DnsResolver;
3637
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
3738
import org.apache.hc.client5.http.observation.binder.ConnPoolMeters;
3839
import org.apache.hc.client5.http.observation.binder.ConnPoolMetersAsync;
40+
import org.apache.hc.client5.http.observation.impl.MeteredAsyncConnectionManager;
41+
import org.apache.hc.client5.http.observation.impl.MeteredConnectionManager;
3942
import org.apache.hc.client5.http.observation.impl.ObservationAsyncExecInterceptor;
4043
import org.apache.hc.client5.http.observation.impl.ObservationClassicExecInterceptor;
44+
import org.apache.hc.client5.http.observation.impl.MeteredDnsResolver;
45+
import org.apache.hc.client5.http.observation.impl.MeteredTlsStrategy;
4146
import org.apache.hc.client5.http.observation.interceptors.AsyncIoByteCounterExec;
4247
import org.apache.hc.client5.http.observation.interceptors.AsyncTimerExec;
4348
import org.apache.hc.client5.http.observation.interceptors.IoByteCounterExec;
4449
import org.apache.hc.client5.http.observation.interceptors.TimerExec;
50+
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
51+
import org.apache.hc.client5.http.nio.AsyncClientConnectionManager;
4552
import org.apache.hc.core5.util.Args;
53+
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
4654

4755
/**
4856
* Utility class that wires Micrometer / OpenTelemetry instrumentation into
@@ -86,7 +94,9 @@
8694
* that surrounds each execution with a start/stop span.</li>
8795
* <li>Metric interceptors according to {@link ObservingOptions.MetricSet}:
8896
* BASIC (latency timer + response counter), IO (bytes in/out counters),
89-
* and CONN_POOL (pool gauges; classic and async variants).</li>
97+
* and CONN_POOL (pool gauges; classic and async variants). Pool lease
98+
* timing is available when using {@link #meteredConnectionManager} or
99+
* {@link #meteredAsyncConnectionManager}.</li>
90100
* </ul>
91101
*
92102
* <p><strong>Thread safety:</strong> This class is stateless. Methods may be
@@ -461,6 +471,111 @@ public static void enable(final CachingHttpAsyncClientBuilder builder,
461471
if (o.metricSets.contains(ObservingOptions.MetricSet.IO)) {
462472
builder.addExecInterceptorAfter(ChainElement.CACHING.name(), IO_ID, new AsyncIoByteCounterExec(meterReg, o, config));
463473
}
474+
if (o.metricSets.contains(ObservingOptions.MetricSet.CONN_POOL)) {
475+
ConnPoolMetersAsync.bindTo(builder, meterReg, config);
476+
}
477+
}
478+
479+
/**
480+
* Wraps a classic connection manager with Micrometer pool-lease metrics if
481+
* {@link ObservingOptions.MetricSet#CONN_POOL} is enabled. Otherwise returns
482+
* the delegate unchanged.
483+
*
484+
* @param delegate connection manager to wrap
485+
* @param meterReg meter registry to register meters with (must not be {@code null})
486+
* @param opts observation/metric options; when {@code null} {@link ObservingOptions#DEFAULT} is used
487+
* @param mc metric configuration; when {@code null} {@link MetricConfig#DEFAULT} is used
488+
* @return metered connection manager or original delegate
489+
* @since 5.7
490+
*/
491+
public static HttpClientConnectionManager meteredConnectionManager(final HttpClientConnectionManager delegate,
492+
final MeterRegistry meterReg,
493+
final ObservingOptions opts,
494+
final MetricConfig mc) {
495+
Args.notNull(delegate, "delegate");
496+
Args.notNull(meterReg, "meterRegistry");
497+
final ObservingOptions o = opts != null ? opts : ObservingOptions.DEFAULT;
498+
final MetricConfig config = mc != null ? mc : MetricConfig.DEFAULT;
499+
if (!o.metricSets.contains(ObservingOptions.MetricSet.CONN_POOL)) {
500+
return delegate;
501+
}
502+
return new MeteredConnectionManager(delegate, meterReg, config, o);
503+
}
504+
505+
/**
506+
* Wraps an async connection manager with Micrometer pool-lease metrics if
507+
* {@link ObservingOptions.MetricSet#CONN_POOL} is enabled. Otherwise returns
508+
* the delegate unchanged.
509+
*
510+
* @param delegate connection manager to wrap
511+
* @param meterReg meter registry to register meters with (must not be {@code null})
512+
* @param opts observation/metric options; when {@code null} {@link ObservingOptions#DEFAULT} is used
513+
* @param mc metric configuration; when {@code null} {@link MetricConfig#DEFAULT} is used
514+
* @return metered connection manager or original delegate
515+
* @since 5.7
516+
*/
517+
public static AsyncClientConnectionManager meteredAsyncConnectionManager(final AsyncClientConnectionManager delegate,
518+
final MeterRegistry meterReg,
519+
final ObservingOptions opts,
520+
final MetricConfig mc) {
521+
Args.notNull(delegate, "delegate");
522+
Args.notNull(meterReg, "meterRegistry");
523+
final ObservingOptions o = opts != null ? opts : ObservingOptions.DEFAULT;
524+
final MetricConfig config = mc != null ? mc : MetricConfig.DEFAULT;
525+
if (!o.metricSets.contains(ObservingOptions.MetricSet.CONN_POOL)) {
526+
return delegate;
527+
}
528+
return new MeteredAsyncConnectionManager(delegate, meterReg, config, o);
529+
}
530+
531+
/**
532+
* Wraps a DNS resolver with Micrometer metrics if {@link ObservingOptions.MetricSet#DNS}
533+
* is enabled. Otherwise returns the delegate unchanged.
534+
*
535+
* @param delegate underlying DNS resolver
536+
* @param meterReg meter registry to register meters with (must not be {@code null})
537+
* @param opts observation/metric options; when {@code null} {@link ObservingOptions#DEFAULT} is used
538+
* @param mc metric configuration; when {@code null} {@link MetricConfig#DEFAULT} is used
539+
* @return metered resolver or original delegate
540+
* @since 5.7
541+
*/
542+
public static DnsResolver meteredDnsResolver(final DnsResolver delegate,
543+
final MeterRegistry meterReg,
544+
final ObservingOptions opts,
545+
final MetricConfig mc) {
546+
Args.notNull(delegate, "delegate");
547+
Args.notNull(meterReg, "meterRegistry");
548+
final ObservingOptions o = opts != null ? opts : ObservingOptions.DEFAULT;
549+
final MetricConfig config = mc != null ? mc : MetricConfig.DEFAULT;
550+
if (!o.metricSets.contains(ObservingOptions.MetricSet.DNS)) {
551+
return delegate;
552+
}
553+
return new MeteredDnsResolver(delegate, meterReg, config, o);
554+
}
555+
556+
/**
557+
* Wraps a TLS strategy with Micrometer metrics if {@link ObservingOptions.MetricSet#TLS}
558+
* is enabled. Otherwise returns the delegate unchanged.
559+
*
560+
* @param delegate TLS strategy to wrap
561+
* @param meterReg meter registry to register meters with (must not be {@code null})
562+
* @param opts observation/metric options; when {@code null} {@link ObservingOptions#DEFAULT} is used
563+
* @param mc metric configuration; when {@code null} {@link MetricConfig#DEFAULT} is used
564+
* @return metered strategy or original delegate
565+
* @since 5.7
566+
*/
567+
public static TlsStrategy meteredTlsStrategy(final TlsStrategy delegate,
568+
final MeterRegistry meterReg,
569+
final ObservingOptions opts,
570+
final MetricConfig mc) {
571+
Args.notNull(delegate, "delegate");
572+
Args.notNull(meterReg, "meterRegistry");
573+
final ObservingOptions o = opts != null ? opts : ObservingOptions.DEFAULT;
574+
final MetricConfig config = mc != null ? mc : MetricConfig.DEFAULT;
575+
if (!o.metricSets.contains(ObservingOptions.MetricSet.TLS)) {
576+
return delegate;
577+
}
578+
return new MeteredTlsStrategy(delegate, meterReg, config, o);
464579
}
465580

466581
/**

httpclient5-observation/src/main/java/org/apache/hc/client5/http/observation/ObservingOptions.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ public final class ObservingOptions {
4343

4444
/**
4545
* Which metric groups to enable.
46+
* <p>
47+
* {@link MetricSet#TLS} and {@link MetricSet#DNS} are applied when using
48+
* {@link org.apache.hc.client5.http.observation.HttpClientObservationSupport#meteredTlsStrategy}
49+
* and {@link org.apache.hc.client5.http.observation.HttpClientObservationSupport#meteredDnsResolver}
50+
* to wrap the underlying TLS strategy or DNS resolver.
4651
*/
4752
public enum MetricSet { BASIC, IO, CONN_POOL, TLS, DNS }
4853

0 commit comments

Comments
 (0)