diff --git a/tritium-registry/src/main/java/com/palantir/tritium/metrics/registry/DefaultTaggedMetricRegistry.java b/tritium-registry/src/main/java/com/palantir/tritium/metrics/registry/DefaultTaggedMetricRegistry.java index 75015d32f..1c535e88b 100644 --- a/tritium-registry/src/main/java/com/palantir/tritium/metrics/registry/DefaultTaggedMetricRegistry.java +++ b/tritium-registry/src/main/java/com/palantir/tritium/metrics/registry/DefaultTaggedMetricRegistry.java @@ -48,7 +48,12 @@ public static TaggedMetricRegistry getDefault() { @Override public Counter counter(MetricName metricName) { - return getOrAdd(metricName, Counter.class, Counter::new); + return counter(metricName, Counter::new); + } + + @Override + public Counter counter(MetricName metricName, Supplier counterSupplier) { + return getOrAdd(metricName, Counter.class, counterSupplier); } @Override @@ -58,17 +63,32 @@ public Gauge gauge(MetricName metricName, Gauge gauge) { @Override public Histogram histogram(MetricName metricName) { - return getOrAdd(metricName, Histogram.class, () -> new Histogram(new ExponentiallyDecayingReservoir())); + return histogram(metricName, () -> new Histogram(new ExponentiallyDecayingReservoir())); + } + + @Override + public Histogram histogram(MetricName metricName, Supplier histogramSupplier) { + return getOrAdd(metricName, Histogram.class, histogramSupplier); } @Override public Meter meter(MetricName metricName) { - return getOrAdd(metricName, Meter.class, Meter::new); + return meter(metricName, Meter::new); + } + + @Override + public Meter meter(MetricName metricName, Supplier meterSupplier) { + return getOrAdd(metricName, Meter.class, meterSupplier); } @Override public Timer timer(MetricName metricName) { - return getOrAdd(metricName, Timer.class, Timer::new); + return timer(metricName, Timer::new); + } + + @Override + public Timer timer(MetricName metricName, Supplier timerSupplier) { + return getOrAdd(metricName, Timer.class, timerSupplier); } @Override diff --git a/tritium-registry/src/main/java/com/palantir/tritium/metrics/registry/TaggedMetricRegistry.java b/tritium-registry/src/main/java/com/palantir/tritium/metrics/registry/TaggedMetricRegistry.java index 0db1b27ea..044e9a0f0 100644 --- a/tritium-registry/src/main/java/com/palantir/tritium/metrics/registry/TaggedMetricRegistry.java +++ b/tritium-registry/src/main/java/com/palantir/tritium/metrics/registry/TaggedMetricRegistry.java @@ -24,6 +24,7 @@ import com.codahale.metrics.Timer; import java.util.Map; import java.util.Optional; +import java.util.function.Supplier; /** * Similar to {@link com.codahale.metrics.MetricRegistry} but allows tagging of {@link Metric}s. @@ -38,6 +39,8 @@ public interface TaggedMetricRegistry { */ Timer timer(MetricName metricName); + Timer timer(MetricName metricName, Supplier timerSupplier); + /** * Returns existing or new meter metric for the specified metric name. * @@ -46,6 +49,8 @@ public interface TaggedMetricRegistry { */ Meter meter(MetricName metricName); + Meter meter(MetricName metricName, Supplier meterSupplier); + /** * Returns existing or new histogram metric for the specified metric name. * @@ -54,6 +59,8 @@ public interface TaggedMetricRegistry { */ Histogram histogram(MetricName metricName); + Histogram histogram(MetricName metricName, Supplier histogramSupplier); + /** * Returns existing or new gauge metric for the specified metric name. * @@ -72,6 +79,8 @@ public interface TaggedMetricRegistry { */ Counter counter(MetricName metricName); + Counter counter(MetricName metricName, Supplier counterSupplier); + /** * Returns a map of registered metrics. * diff --git a/tritium-registry/src/test/java/com/palantir/tritium/metrics/registry/TaggedMetricRegistryTest.java b/tritium-registry/src/test/java/com/palantir/tritium/metrics/registry/TaggedMetricRegistryTest.java index 98e4ad3fb..4bfa522aa 100644 --- a/tritium-registry/src/test/java/com/palantir/tritium/metrics/registry/TaggedMetricRegistryTest.java +++ b/tritium-registry/src/test/java/com/palantir/tritium/metrics/registry/TaggedMetricRegistryTest.java @@ -18,16 +18,22 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.when; import com.codahale.metrics.Counter; +import com.codahale.metrics.ExponentiallyDecayingReservoir; import com.codahale.metrics.Gauge; import com.codahale.metrics.Histogram; import com.codahale.metrics.Meter; import com.codahale.metrics.Metric; import com.codahale.metrics.Timer; import java.util.Optional; +import java.util.function.Supplier; import org.junit.Before; import org.junit.Test; +import org.mockito.Mockito; public final class TaggedMetricRegistryTest { @@ -41,21 +47,46 @@ public void before() { registry = new DefaultTaggedMetricRegistry(); } + interface SuppliedMetricMethod { + T metric(MetricName metricName, Supplier supplier); + } + + interface MetricMethod { + T metric(MetricName metricName); + } + + private void testNonsuppliedCall(MetricMethod registryMethod) { + T metric1 = registryMethod.metric(METRIC_1); + T metric2 = registryMethod.metric(METRIC_2); + + assertThat(metric1).isNotSameAs(metric2); + assertThat(registryMethod.metric(METRIC_1)).isSameAs(metric1); + assertThat(registryMethod.metric(METRIC_2)).isSameAs(metric2); + } + + private void testSuppliedCall(SuppliedMetricMethod registryMethod, T mock1, T mock2) { + Supplier mockSupplier = mock(Supplier.class); + when(mockSupplier.get()).thenReturn(mock1).thenReturn(mock2); + + assertThat(registryMethod.metric(METRIC_1, mockSupplier)).isSameAs(mock1); + assertThat(registryMethod.metric(METRIC_2, mockSupplier)).isSameAs(mock2); + assertThat(registryMethod.metric(METRIC_1, mockSupplier)).isSameAs(mock1); // should be memoized + assertThat(registryMethod.metric(METRIC_2, mockSupplier)).isSameAs(mock2); // should be memoized + + Mockito.verify(mockSupplier, times(2)).get(); + } + @Test public void testCounter() { - Counter counter1 = registry.counter(METRIC_1); - Counter counter2 = registry.counter(METRIC_2); - - // ensure new counters are created - assertThat(counter1.getCount()).isEqualTo(0); - assertThat(counter2.getCount()).isEqualTo(0); + testNonsuppliedCall(registry::counter); + } - // ensure they're not the same and can be retrieved using the same name - assertThat(counter1).isNotSameAs(counter2); - assertThat(registry.counter(METRIC_1)).isSameAs(counter1); - assertThat(registry.counter(METRIC_2)).isSameAs(counter2); + @Test + public void testSuppliedCounter() { + testSuppliedCall(registry::counter, new Counter(), new Counter()); } + @Test public void testGauge() { Gauge gauge1 = registry.gauge(METRIC_1, () -> 1); @@ -71,41 +102,34 @@ public void testGauge() { @Test public void testHistogram() { - Histogram histogram1 = registry.histogram(METRIC_1); - Histogram histogram2 = registry.histogram(METRIC_2); - - assertThat(histogram1.getCount()).isEqualTo(0); - assertThat(histogram2.getCount()).isEqualTo(0); + testNonsuppliedCall(registry::histogram); + } - assertThat(histogram1).isNotSameAs(histogram2); - assertThat(registry.histogram(METRIC_1)).isSameAs(histogram1); - assertThat(registry.histogram(METRIC_2)).isSameAs(histogram2); + @Test + public void testSuppliedHistogram() { + testSuppliedCall(registry::histogram, + new Histogram(new ExponentiallyDecayingReservoir()), + new Histogram(new ExponentiallyDecayingReservoir())); } @Test public void testMeter() { - Meter meter1 = registry.meter(METRIC_1); - Meter meter2 = registry.meter(METRIC_2); - - assertThat(meter1.getCount()).isEqualTo(0); - assertThat(meter2.getCount()).isEqualTo(0); + testNonsuppliedCall(registry::meter); + } - assertThat(meter1).isNotSameAs(meter2); - assertThat(registry.meter(METRIC_1)).isSameAs(meter1); - assertThat(registry.meter(METRIC_2)).isSameAs(meter2); + @Test + public void testSuppliedMeter() { + testSuppliedCall(registry::meter, new Meter(), new Meter()); } @Test public void testTimer() { - Timer timer1 = registry.timer(METRIC_1); - Timer timer2 = registry.timer(METRIC_2); - - assertThat(timer1.getCount()).isEqualTo(0); - assertThat(timer2.getCount()).isEqualTo(0); + testNonsuppliedCall(registry::timer); + } - assertThat(timer1).isNotSameAs(timer2); - assertThat(registry.timer(METRIC_1)).isSameAs(timer1); - assertThat(registry.timer(METRIC_2)).isSameAs(timer2); + @Test + public void testSuppliedTimer() { + testSuppliedCall(registry::timer, new Timer(), new Timer()); } @Test