Skip to content

Commit

Permalink
Add a more type safe way of registering gauges (#2792)
Browse files Browse the repository at this point in the history
Refs #2642
  • Loading branch information
DanyBv committed Nov 18, 2022
1 parent a743db7 commit 67d7c0c
Show file tree
Hide file tree
Showing 18 changed files with 217 additions and 177 deletions.
Expand Up @@ -58,31 +58,31 @@ public InstrumentedExecutorService(ExecutorService delegate, MetricRegistry regi

if (delegate instanceof ThreadPoolExecutor) {
ThreadPoolExecutor executor = (ThreadPoolExecutor) delegate;
registry.register(MetricRegistry.name(name, "pool.size"),
(Gauge<Integer>) executor::getPoolSize);
registry.register(MetricRegistry.name(name, "pool.core"),
(Gauge<Integer>) executor::getCorePoolSize);
registry.register(MetricRegistry.name(name, "pool.max"),
(Gauge<Integer>) executor::getMaximumPoolSize);
registry.registerGauge(MetricRegistry.name(name, "pool.size"),
executor::getPoolSize);
registry.registerGauge(MetricRegistry.name(name, "pool.core"),
executor::getCorePoolSize);
registry.registerGauge(MetricRegistry.name(name, "pool.max"),
executor::getMaximumPoolSize);
final BlockingQueue<Runnable> queue = executor.getQueue();
registry.register(MetricRegistry.name(name, "tasks.active"),
(Gauge<Integer>) executor::getActiveCount);
registry.register(MetricRegistry.name(name, "tasks.completed"),
(Gauge<Long>) executor::getCompletedTaskCount);
registry.register(MetricRegistry.name(name, "tasks.queued"),
(Gauge<Integer>) queue::size);
registry.register(MetricRegistry.name(name, "tasks.capacity"),
(Gauge<Integer>) queue::remainingCapacity);
registry.registerGauge(MetricRegistry.name(name, "tasks.active"),
executor::getActiveCount);
registry.registerGauge(MetricRegistry.name(name, "tasks.completed"),
executor::getCompletedTaskCount);
registry.registerGauge(MetricRegistry.name(name, "tasks.queued"),
queue::size);
registry.registerGauge(MetricRegistry.name(name, "tasks.capacity"),
queue::remainingCapacity);
} else if (delegate instanceof ForkJoinPool) {
ForkJoinPool forkJoinPool = (ForkJoinPool) delegate;
registry.register(MetricRegistry.name(name, "tasks.stolen"),
(Gauge<Long>) forkJoinPool::getStealCount);
registry.register(MetricRegistry.name(name, "tasks.queued"),
(Gauge<Long>) forkJoinPool::getQueuedTaskCount);
registry.register(MetricRegistry.name(name, "threads.active"),
(Gauge<Integer>) forkJoinPool::getActiveThreadCount);
registry.register(MetricRegistry.name(name, "threads.running"),
(Gauge<Integer>) forkJoinPool::getRunningThreadCount);
registry.registerGauge(MetricRegistry.name(name, "tasks.stolen"),
forkJoinPool::getStealCount);
registry.registerGauge(MetricRegistry.name(name, "tasks.queued"),
forkJoinPool::getQueuedTaskCount);
registry.registerGauge(MetricRegistry.name(name, "threads.active"),
forkJoinPool::getActiveThreadCount);
registry.registerGauge(MetricRegistry.name(name, "threads.running"),
forkJoinPool::getRunningThreadCount);
}
}

Expand Down
Expand Up @@ -68,6 +68,25 @@ protected ConcurrentMap<MetricName, Metric> buildMap() {
return new ConcurrentHashMap<>();
}

/**
* See {@link #registerGauge(MetricName, Gauge)}
*/
public <T> Gauge<T> registerGauge(String name, Gauge<T> metric) throws IllegalArgumentException {
return register(MetricName.build(name), metric);
}

/**
* Given a {@link Gauge}, registers it under the given name and returns it
*
* @param name the name of the gauge
* @param <T> the type of the gauge's value
* @return the registered {@link Gauge}
* @since 4.2.10
*/
public <T> Gauge<T> registerGauge(MetricName name, Gauge<T> metric) throws IllegalArgumentException {
return register(name, metric);
}

/**
* See {@link #register(MetricName, Metric)}
*/
Expand All @@ -91,7 +110,7 @@ public <T extends Metric> T register(MetricName name, T metric) throws IllegalAr
}

if (metric instanceof MetricRegistry) {
final MetricRegistry childRegistry = (MetricRegistry)metric;
final MetricRegistry childRegistry = (MetricRegistry) metric;
final MetricName childName = name;
childRegistry.addListener(new MetricRegistryListener() {
@Override
Expand Down
Expand Up @@ -664,4 +664,18 @@ public void registerNullMetric() {
assertThatThrownBy(() -> registry.register("any_name", null))
.hasMessage("metric == null");
}

@Test
public void infersGaugeType() {
Gauge<Long> gauge = registry.registerGauge(GAUGE, () -> 10_000_000_000L);

assertThat(gauge.getValue()).isEqualTo(10_000_000_000L);
}

@Test
public void registersGaugeAsLambda() {
registry.registerGauge(GAUGE, () -> 3.14);

assertThat(registry.gauge(GAUGE).getValue()).isEqualTo(3.14);
}
}
@@ -1,6 +1,5 @@
package io.dropwizard.metrics5.ehcache;

import io.dropwizard.metrics5.Gauge;
import io.dropwizard.metrics5.MetricName;
import io.dropwizard.metrics5.MetricRegistry;
import io.dropwizard.metrics5.Timer;
Expand All @@ -12,6 +11,8 @@

import java.io.Serializable;

import static io.dropwizard.metrics5.MetricRegistry.name;

/**
* An instrumented {@link Ehcache} instance.
*/
Expand Down Expand Up @@ -116,57 +117,57 @@ public class InstrumentedEhcache extends EhcacheDecoratorAdapter {
*/
public static Ehcache instrument(MetricRegistry registry, final Ehcache cache) {

final MetricName prefix = MetricRegistry.name(cache.getClass(), cache.getName());
registry.register(prefix.resolve("hits"),
(Gauge<Long>) () -> cache.getStatistics().cacheHitCount());
final MetricName prefix = name(cache.getClass(), cache.getName());
registry.registerGauge(prefix.resolve("hits"),
() -> cache.getStatistics().cacheHitCount());

registry.register(prefix.resolve("in-memory-hits"),
(Gauge<Long>) () -> cache.getStatistics().localHeapHitCount());
registry.registerGauge(prefix.resolve("in-memory-hits"),
() -> cache.getStatistics().localHeapHitCount());

registry.register(prefix.resolve("off-heap-hits"),
(Gauge<Long>) () -> cache.getStatistics().localOffHeapHitCount());
registry.registerGauge(prefix.resolve("off-heap-hits"),
() -> cache.getStatistics().localOffHeapHitCount());

registry.register(prefix.resolve("on-disk-hits"),
(Gauge<Long>) () -> cache.getStatistics().localDiskHitCount());
registry.registerGauge(prefix.resolve("on-disk-hits"),
() -> cache.getStatistics().localDiskHitCount());

registry.register(prefix.resolve("misses"),
(Gauge<Long>) () -> cache.getStatistics().cacheMissCount());
registry.registerGauge(prefix.resolve("misses"),
() -> cache.getStatistics().cacheMissCount());

registry.register(prefix.resolve("in-memory-misses"),
(Gauge<Long>) () -> cache.getStatistics().localHeapMissCount());
registry.registerGauge(prefix.resolve("in-memory-misses"),
() -> cache.getStatistics().localHeapMissCount());

registry.register(prefix.resolve("off-heap-misses"),
(Gauge<Long>) () -> cache.getStatistics().localOffHeapMissCount());
registry.registerGauge(prefix.resolve("off-heap-misses"),
() -> cache.getStatistics().localOffHeapMissCount());

registry.register(prefix.resolve("on-disk-misses"),
(Gauge<Long>) () -> cache.getStatistics().localDiskMissCount());
registry.registerGauge(prefix.resolve("on-disk-misses"),
() -> cache.getStatistics().localDiskMissCount());

registry.register(prefix.resolve("objects"),
(Gauge<Long>) () -> cache.getStatistics().getSize());
registry.registerGauge(prefix.resolve("objects"),
() -> cache.getStatistics().getSize());

registry.register(prefix.resolve("in-memory-objects"),
(Gauge<Long>) () -> cache.getStatistics().getLocalHeapSize());
registry.registerGauge(prefix.resolve("in-memory-objects"),
() -> cache.getStatistics().getLocalHeapSize());

registry.register(prefix.resolve("off-heap-objects"),
(Gauge<Long>) () -> cache.getStatistics().getLocalOffHeapSize());
registry.registerGauge(prefix.resolve("off-heap-objects"),
() -> cache.getStatistics().getLocalOffHeapSize());

registry.register(prefix.resolve("on-disk-objects"),
(Gauge<Long>) () -> cache.getStatistics().getLocalDiskSize());
registry.registerGauge(prefix.resolve("on-disk-objects"),
() -> cache.getStatistics().getLocalDiskSize());

registry.register(prefix.resolve("mean-get-time"),
(Gauge<Double>) () -> cache.getStatistics().cacheGetOperation().latency().average().value());
registry.registerGauge(prefix.resolve("mean-get-time"),
() -> cache.getStatistics().cacheGetOperation().latency().average().value());

registry.register(prefix.resolve("mean-search-time"),
(Gauge<Double>) () -> cache.getStatistics().cacheSearchOperation().latency().average().value());
registry.registerGauge(prefix.resolve("mean-search-time"),
() -> cache.getStatistics().cacheSearchOperation().latency().average().value());

registry.register(prefix.resolve("eviction-count"),
(Gauge<Long>) () -> cache.getStatistics().cacheEvictionOperation().count().value());
registry.registerGauge(prefix.resolve("eviction-count"),
() -> cache.getStatistics().cacheEvictionOperation().count().value());

registry.register(prefix.resolve("searches-per-second"),
(Gauge<Double>) () -> cache.getStatistics().cacheSearchOperation().rate().value());
registry.registerGauge(prefix.resolve("searches-per-second"),
() -> cache.getStatistics().cacheSearchOperation().rate().value());

registry.register(prefix.resolve("writer-queue-size"),
(Gauge<Long>) () -> cache.getStatistics().getWriterQueueLength());
registry.registerGauge(prefix.resolve("writer-queue-size"),
() -> cache.getStatistics().getWriterQueueLength());

return new InstrumentedEhcache(registry, cache);
}
Expand Down
Expand Up @@ -11,6 +11,7 @@
import org.junit.Test;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;

public class InstrumentedEhcacheTest {
private static final CacheManager MANAGER = CacheManager.create();
Expand All @@ -23,6 +24,27 @@ public void setUp() {
final Cache c = new Cache(new CacheConfiguration("test", 100));
MANAGER.addCache(c);
this.cache = InstrumentedEhcache.instrument(registry, c);
assertThat(registry.getGauges().entrySet().stream()
.map(e -> entry(e.getKey().getKey(), (Number) e.getValue().getValue())))
.containsOnly(
entry("net.sf.ehcache.Cache.test.eviction-count", 0L),
entry("net.sf.ehcache.Cache.test.hits", 0L),
entry("net.sf.ehcache.Cache.test.in-memory-hits", 0L),
entry("net.sf.ehcache.Cache.test.in-memory-misses", 0L),
entry("net.sf.ehcache.Cache.test.in-memory-objects", 0L),
entry("net.sf.ehcache.Cache.test.mean-get-time", Double.NaN),
entry("net.sf.ehcache.Cache.test.mean-search-time", Double.NaN),
entry("net.sf.ehcache.Cache.test.misses", 0L),
entry("net.sf.ehcache.Cache.test.objects", 0L),
entry("net.sf.ehcache.Cache.test.off-heap-hits", 0L),
entry("net.sf.ehcache.Cache.test.off-heap-misses", 0L),
entry("net.sf.ehcache.Cache.test.off-heap-objects", 0L),
entry("net.sf.ehcache.Cache.test.on-disk-hits", 0L),
entry("net.sf.ehcache.Cache.test.on-disk-misses", 0L),
entry("net.sf.ehcache.Cache.test.on-disk-objects", 0L),
entry("net.sf.ehcache.Cache.test.searches-per-second", 0.0),
entry("net.sf.ehcache.Cache.test.writer-queue-size", 0L)
);
}

@Test
Expand Down
@@ -1,6 +1,5 @@
package io.dropwizard.metrics5.httpasyncclient;

import io.dropwizard.metrics5.Gauge;
import io.dropwizard.metrics5.MetricRegistry;
import org.apache.http.config.Registry;
import org.apache.http.conn.DnsResolver;
Expand All @@ -20,26 +19,18 @@ public class InstrumentedNClientConnManager extends PoolingNHttpClientConnection

public InstrumentedNClientConnManager(final ConnectingIOReactor ioreactor, final NHttpConnectionFactory<ManagedNHttpClientConnection> connFactory, final SchemePortResolver schemePortResolver, final MetricRegistry metricRegistry, final Registry<SchemeIOSessionStrategy> iosessionFactoryRegistry, final long timeToLive, final TimeUnit tunit, final DnsResolver dnsResolver, final String name) {
super(ioreactor, connFactory, iosessionFactoryRegistry, schemePortResolver, dnsResolver, timeToLive, tunit);
metricRegistry.register(name(NHttpClientConnectionManager.class, name, "available-connections"),
(Gauge<Integer>) () -> {
// this acquires a lock on the connection pool; remove if contention sucks
return getTotalStats().getAvailable();
});
metricRegistry.register(name(NHttpClientConnectionManager.class, name, "leased-connections"),
(Gauge<Integer>) () -> {
// this acquires a lock on the connection pool; remove if contention sucks
return getTotalStats().getLeased();
});
metricRegistry.register(name(NHttpClientConnectionManager.class, name, "max-connections"),
(Gauge<Integer>) () -> {
// this acquires a lock on the connection pool; remove if contention sucks
return getTotalStats().getMax();
});
metricRegistry.register(name(NHttpClientConnectionManager.class, name, "pending-connections"),
(Gauge<Integer>) () -> {
// this acquires a lock on the connection pool; remove if contention sucks
return getTotalStats().getPending();
});
// this acquires a lock on the connection pool; remove if contention sucks
metricRegistry.registerGauge(name(NHttpClientConnectionManager.class, name, "available-connections"),
() -> getTotalStats().getAvailable());
// this acquires a lock on the connection pool; remove if contention sucks
metricRegistry.registerGauge(name(NHttpClientConnectionManager.class, name, "leased-connections"),
() -> getTotalStats().getLeased());
// this acquires a lock on the connection pool; remove if contention sucks
metricRegistry.registerGauge(name(NHttpClientConnectionManager.class, name, "max-connections"),
() -> getTotalStats().getMax());
// this acquires a lock on the connection pool; remove if contention sucks
metricRegistry.registerGauge(name(NHttpClientConnectionManager.class, name, "pending-connections"),
() -> getTotalStats().getPending());
}

}
@@ -1,6 +1,5 @@
package io.dropwizard.metrics5.httpclient;

import io.dropwizard.metrics5.Gauge;
import io.dropwizard.metrics5.MetricRegistry;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
Expand Down Expand Up @@ -104,26 +103,18 @@ public InstrumentedHttpClientConnectionManager(MetricRegistry metricsRegistry,
this.metricsRegistry = metricsRegistry;
this.name = name;

metricsRegistry.register(name(HttpClientConnectionManager.class, name, "available-connections"),
(Gauge<Integer>) () -> {
// this acquires a lock on the connection pool; remove if contention sucks
return getTotalStats().getAvailable();
});
metricsRegistry.register(name(HttpClientConnectionManager.class, name, "leased-connections"),
(Gauge<Integer>) () -> {
// this acquires a lock on the connection pool; remove if contention sucks
return getTotalStats().getLeased();
});
metricsRegistry.register(name(HttpClientConnectionManager.class, name, "max-connections"),
(Gauge<Integer>) () -> {
// this acquires a lock on the connection pool; remove if contention sucks
return getTotalStats().getMax();
});
metricsRegistry.register(name(HttpClientConnectionManager.class, name, "pending-connections"),
(Gauge<Integer>) () -> {
// this acquires a lock on the connection pool; remove if contention sucks
return getTotalStats().getPending();
});
// this acquires a lock on the connection pool; remove if contention sucks
metricsRegistry.registerGauge(name(HttpClientConnectionManager.class, name, "available-connections"),
() -> getTotalStats().getAvailable());
// this acquires a lock on the connection pool; remove if contention sucks
metricsRegistry.registerGauge(name(HttpClientConnectionManager.class, name, "leased-connections"),
() -> getTotalStats().getLeased());
// this acquires a lock on the connection pool; remove if contention sucks
metricsRegistry.registerGauge(name(HttpClientConnectionManager.class, name, "max-connections"),
() -> getTotalStats().getMax());
// this acquires a lock on the connection pool; remove if contention sucks
metricsRegistry.registerGauge(name(HttpClientConnectionManager.class, name, "pending-connections"),
() -> getTotalStats().getPending());
}

@Override
Expand Down

0 comments on commit 67d7c0c

Please sign in to comment.