diff --git a/common/pom.xml b/common/pom.xml
index a8fdd27..09136a4 100644
--- a/common/pom.xml
+++ b/common/pom.xml
@@ -199,10 +199,17 @@
jackson-databind
${jackson.new.version}
-
+
+
+
+ org.mockito
+ mockito-all
+ ${mockito-all.version}
+ test
diff --git a/common/src/java/org/apache/hadoop/hive/common/metrics/metrics2/CodahaleMetrics.java b/common/src/java/org/apache/hadoop/hive/common/metrics/metrics2/CodahaleMetrics.java
index 4c43367..1b08735 100644
--- a/common/src/java/org/apache/hadoop/hive/common/metrics/metrics2/CodahaleMetrics.java
+++ b/common/src/java/org/apache/hadoop/hive/common/metrics/metrics2/CodahaleMetrics.java
@@ -34,7 +34,7 @@
import com.codahale.metrics.jvm.MemoryUsageGaugeSet;
import com.codahale.metrics.jvm.ThreadStatesGaugeSet;
import com.fasterxml.jackson.databind.ObjectMapper;
-import com.github.joshelser.dropwizard.metrics.hadoop.HadoopMetrics2Reporter;
+import org.apache.hive.common.util.HadoopMetrics2Reporter;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Splitter;
import com.google.common.cache.CacheBuilder;
diff --git a/common/src/java/org/apache/hive/common/util/HadoopMetrics2Reporter.java b/common/src/java/org/apache/hive/common/util/HadoopMetrics2Reporter.java
new file mode 100644
index 0000000..270be97
--- /dev/null
+++ b/common/src/java/org/apache/hive/common/util/HadoopMetrics2Reporter.java
@@ -0,0 +1,452 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hive.common.util;
+
+import org.apache.hadoop.metrics2.MetricsCollector;
+import org.apache.hadoop.metrics2.MetricsInfo;
+import org.apache.hadoop.metrics2.MetricsRecordBuilder;
+import org.apache.hadoop.metrics2.MetricsSource;
+import org.apache.hadoop.metrics2.MetricsSystem;
+import org.apache.hadoop.metrics2.lib.Interns;
+import org.apache.hadoop.metrics2.lib.MetricsRegistry;
+
+import com.codahale.metrics.Counter;
+import com.codahale.metrics.Gauge;
+import com.codahale.metrics.Histogram;
+import com.codahale.metrics.Meter;
+import com.codahale.metrics.MetricFilter;
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.ScheduledReporter;
+import com.codahale.metrics.Snapshot;
+import com.codahale.metrics.Timer;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Iterator;
+import java.util.Map.Entry;
+import java.util.Objects;
+import java.util.SortedMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Local code copy of com.github.joshelser.dropwizard.metrics.hadoop.HadoopMetrics2Reporter
+ * which allows CodaHale metrics to bridge to Hadoop Metrics2.
+ *
+ * Note that the presence of this class inside the hive project is
+ * explicitly intended to be temporary and is being introduced as Deprecated.
+ * It should not be modified here. If you have any contributions to make to this,
+ * please contribute directly to the original project. The reason this is being
+ * introduced here is to fix an issue where the aforementioned class which is a
+ * hive dependency generates an exceptionally large number of INFO level logs due
+ * to the way we use it. Fixing this in a log4j.properties is trivial, but manual
+ * for a lot of people, and thus, having this copy here is a temporary fix till a
+ * newer version of the Metrics2Reporter exists which we can depend on instead.
+ *
+ * Please do *NOT* depend on this from code other than from CodahaleMetrics, this
+ * will be removed soon.
+ */
+
+@Deprecated
+public class HadoopMetrics2Reporter extends ScheduledReporter implements MetricsSource {
+ private static final Logger LOG = LoggerFactory.getLogger(HadoopMetrics2Reporter.class);
+ private static final String EMPTY_STRING = "";
+
+ public static final MetricsInfo RATE_UNIT_LABEL =
+ Interns.info("rate_unit", "The unit of measure for rate metrics");
+ public static final MetricsInfo DURATION_UNIT_LABEL =
+ Interns.info("duration_unit", "The unit of measure of duration metrics");
+
+ /**
+ * Returns a new {@link Builder} for {@link HadoopMetrics2Reporter}.
+ *
+ * @param registry the registry to report
+ * @return a {@link Builder} instance for a {@link HadoopMetrics2Reporter}
+ */
+ public static Builder forRegistry(MetricRegistry registry) {
+ return new Builder(registry);
+ }
+
+ /**
+ * A builder to create {@link HadoopMetrics2Reporter} instances.
+ */
+ public static class Builder {
+ private final MetricRegistry registry;
+ private MetricFilter filter;
+ private TimeUnit rateUnit;
+ private TimeUnit durationUnit;
+ private String recordContext;
+
+ private Builder(MetricRegistry registry) {
+ this.registry = registry;
+ this.filter = MetricFilter.ALL;
+ this.rateUnit = TimeUnit.SECONDS;
+ this.durationUnit = TimeUnit.MILLISECONDS;
+ }
+
+ /**
+ * Convert rates to the given time unit. Defaults to {@link TimeUnit#SECONDS}.
+ *
+ * @param rateUnit a unit of time
+ * @return {@code this}
+ */
+ public Builder convertRatesTo(TimeUnit rateUnit) {
+ this.rateUnit = Objects.requireNonNull(rateUnit);
+ return this;
+ }
+
+ /**
+ * Convert durations to the given time unit. Defaults to {@link TimeUnit#MILLISECONDS}.
+ *
+ * @param durationUnit a unit of time
+ * @return {@code this}
+ */
+ public Builder convertDurationsTo(TimeUnit durationUnit) {
+ this.durationUnit = Objects.requireNonNull(durationUnit);
+ return this;
+ }
+
+ /**
+ * Only report metrics which match the given filter. Defaults to {@link MetricFilter#ALL}.
+ *
+ * @param filter a {@link MetricFilter}
+ * @return {@code this}
+ */
+ public Builder filter(MetricFilter filter) {
+ this.filter = Objects.requireNonNull(filter);
+ return this;
+ }
+
+ /**
+ * A "context" name that will be added as a tag on each emitted metric record. Defaults to
+ * no "context" attribute on each record.
+ *
+ * @param recordContext The "context" tag
+ * @return {@code this}
+ */
+ public Builder recordContext(String recordContext) {
+ this.recordContext = Objects.requireNonNull(recordContext);
+ return this;
+ }
+
+ /**
+ * Builds a {@link HadoopMetrics2Reporter} with the given properties, making metrics available
+ * to the Hadoop Metrics2 framework (any configured {@link MetricsSource}s.
+ *
+ * @param metrics2System The Hadoop Metrics2 system instance.
+ * @param jmxContext The JMX "path", e.g. {@code "MyServer,sub=Requests"}.
+ * @param description A description these metrics.
+ * @param recordName A suffix included on each record to identify it.
+ *
+ * @return a {@link HadoopMetrics2Reporter}
+ */
+ public HadoopMetrics2Reporter build(MetricsSystem metrics2System, String jmxContext,
+ String description, String recordName) {
+ return new HadoopMetrics2Reporter(registry,
+ rateUnit,
+ durationUnit,
+ filter,
+ metrics2System,
+ Objects.requireNonNull(jmxContext),
+ description,
+ recordName,
+ recordContext);
+ }
+ }
+
+ private final MetricsRegistry metrics2Registry;
+ private final MetricsSystem metrics2System;
+ private final String recordName;
+ private final String context;
+
+ @SuppressWarnings("rawtypes")
+ private final ConcurrentLinkedQueue> dropwizardGauges;
+ private final ConcurrentLinkedQueue> dropwizardCounters;
+ private final ConcurrentLinkedQueue> dropwizardHistograms;
+ private final ConcurrentLinkedQueue> dropwizardMeters;
+ private final ConcurrentLinkedQueue> dropwizardTimers;
+ private HadoopMetrics2Reporter(MetricRegistry registry, TimeUnit rateUnit, TimeUnit durationUnit,
+ MetricFilter filter, MetricsSystem metrics2System, String jmxContext, String description,
+ String recordName, String context) {
+ super(registry, "hadoop-metrics2-reporter", filter, rateUnit, durationUnit);
+ this.metrics2Registry = new MetricsRegistry(Interns.info(jmxContext, description));
+ this.metrics2System = metrics2System;
+ this.recordName = recordName;
+ this.context = context;
+
+ this.dropwizardGauges = new ConcurrentLinkedQueue<>();
+ this.dropwizardCounters = new ConcurrentLinkedQueue<>();
+ this.dropwizardHistograms = new ConcurrentLinkedQueue<>();
+ this.dropwizardMeters = new ConcurrentLinkedQueue<>();
+ this.dropwizardTimers = new ConcurrentLinkedQueue<>();
+
+ // Register this source with the Metrics2 system.
+ // Make sure this is the last thing done as getMetrics() can be called at any time after.
+ this.metrics2System.register(Objects.requireNonNull(jmxContext),
+ Objects.requireNonNull(description), this);
+ }
+
+ @Override public void getMetrics(MetricsCollector collector, boolean all) {
+ MetricsRecordBuilder builder = collector.addRecord(recordName);
+ if (null != context) {
+ builder.setContext(context);
+ }
+
+ snapshotAllMetrics(builder);
+
+ metrics2Registry.snapshot(builder, all);
+ }
+ /**
+ * Consumes the current metrics collected by dropwizard and adds them to the {@code builder}.
+ *
+ * @param builder A record builder
+ */
+ void snapshotAllMetrics(MetricsRecordBuilder builder) {
+ // Pass through the gauges
+ @SuppressWarnings("rawtypes")
+ Iterator> gaugeIterator = dropwizardGauges.iterator();
+ while (gaugeIterator.hasNext()) {
+ @SuppressWarnings("rawtypes")
+ Entry gauge = gaugeIterator.next();
+ final MetricsInfo info = Interns.info(gauge.getKey(), EMPTY_STRING);
+ final Object o = gauge.getValue().getValue();
+
+ // Figure out which gauge types metrics2 supports and call the right method
+ if (o instanceof Integer) {
+ builder.addGauge(info, (int) o);
+ } else if (o instanceof Long) {
+ builder.addGauge(info, (long) o);
+ } else if (o instanceof Float) {
+ builder.addGauge(info, (float) o);
+ } else if (o instanceof Double) {
+ builder.addGauge(info, (double) o);
+ } else {
+ LOG.debug("Ignoring Gauge ({}) with unhandled type: {}", gauge.getKey(), o.getClass());
+ }
+
+ gaugeIterator.remove();
+ }
+
+ // Pass through the counters
+ Iterator> counterIterator = dropwizardCounters.iterator();
+ while (counterIterator.hasNext()) {
+ Entry counter = counterIterator.next();
+ MetricsInfo info = Interns.info(counter.getKey(), EMPTY_STRING);
+ LOG.debug("Adding counter {} {}", info, counter.getValue().getCount());
+ builder.addCounter(info, counter.getValue().getCount());
+ counterIterator.remove();
+ }
+ // Pass through the histograms
+ Iterator> histogramIterator = dropwizardHistograms.iterator();
+ while (histogramIterator.hasNext()) {
+ final Entry entry = histogramIterator.next();
+ final String name = entry.getKey();
+ final Histogram histogram = entry.getValue();
+
+ addSnapshot(builder, name, EMPTY_STRING, histogram.getSnapshot(), histogram.getCount());
+
+ histogramIterator.remove();
+ }
+
+ // Pass through the meter values
+ Iterator> meterIterator = dropwizardMeters.iterator();
+ while (meterIterator.hasNext()) {
+ final Entry meterEntry = meterIterator.next();
+ final String name = meterEntry.getKey();
+ final Meter meter = meterEntry.getValue();
+
+ addMeter(builder, name, EMPTY_STRING, meter.getCount(), meter.getMeanRate(),
+ meter.getOneMinuteRate(), meter.getFiveMinuteRate(), meter.getFifteenMinuteRate());
+
+ meterIterator.remove();
+ }
+
+ // Pass through the timers (meter + histogram)
+ Iterator> timerIterator = dropwizardTimers.iterator();
+ while (timerIterator.hasNext()) {
+ final Entry timerEntry = timerIterator.next();
+ final String name = timerEntry.getKey();
+ final Timer timer = timerEntry.getValue();
+ final Snapshot snapshot = timer.getSnapshot();
+
+ // Add the meter info (mean rate and rate over time windows)
+ addMeter(builder, name, EMPTY_STRING, timer.getCount(), timer.getMeanRate(),
+ timer.getOneMinuteRate(), timer.getFiveMinuteRate(), timer.getFifteenMinuteRate());
+
+ // Count was already added via the meter
+ addSnapshot(builder, name, EMPTY_STRING, snapshot);
+
+ timerIterator.remove();
+ }
+
+ // Add in metadata about what the units the reported metrics are displayed using.
+ builder.tag(RATE_UNIT_LABEL, getRateUnit());
+ builder.tag(DURATION_UNIT_LABEL, getDurationUnit());
+ }
+ /**
+ * Add Dropwizard-Metrics rate information to a Hadoop-Metrics2 record builder, converting the
+ * rates to the appropriate unit.
+ *
+ * @param builder A Hadoop-Metrics2 record builder.
+ * @param name A base name for this record.
+ * @param desc A description for the record.
+ * @param count The number of measured events.
+ * @param meanRate The average measured rate.
+ * @param oneMinuteRate The measured rate over the past minute.
+ * @param fiveMinuteRate The measured rate over the past five minutes
+ * @param fifteenMinuteRate The measured rate over the past fifteen minutes.
+ */
+ private void addMeter(MetricsRecordBuilder builder, String name, String desc, long count,
+ double meanRate, double oneMinuteRate, double fiveMinuteRate, double fifteenMinuteRate) {
+ builder.addGauge(Interns.info(name + "_count", EMPTY_STRING), count);
+ builder.addGauge(Interns.info(name + "_mean_rate", EMPTY_STRING), convertRate(meanRate));
+ builder.addGauge(Interns.info(name + "_1min_rate", EMPTY_STRING), convertRate(oneMinuteRate));
+ builder.addGauge(Interns.info(name + "_5min_rate", EMPTY_STRING), convertRate(fiveMinuteRate));
+ builder.addGauge(Interns.info(name + "_15min_rate", EMPTY_STRING),
+ convertRate(fifteenMinuteRate));
+ }
+
+ /**
+ * Add Dropwizard-Metrics value-distribution data to a Hadoop-Metrics2 record building, converting
+ * the durations to the appropriate unit.
+ *
+ * @param builder A Hadoop-Metrics2 record builder.
+ * @param name A base name for this record.
+ * @param desc A description for this record.
+ * @param snapshot The distribution of measured values.
+ * @param count The number of values which were measured.
+ */
+ private void addSnapshot(MetricsRecordBuilder builder, String name, String desc,
+ Snapshot snapshot, long count) {
+ builder.addGauge(Interns.info(name + "_count", desc), count);
+ addSnapshot(builder, name, desc, snapshot);
+ }
+
+ /**
+ * Add Dropwizard-Metrics value-distribution data to a Hadoop-Metrics2 record building, converting
+ * the durations to the appropriate unit.
+ *
+ * @param builder A Hadoop-Metrics2 record builder.
+ * @param name A base name for this record.
+ * @param desc A description for this record.
+ * @param snapshot The distribution of measured values.
+ */
+ private void addSnapshot(MetricsRecordBuilder builder, String name, String desc,
+ Snapshot snapshot) {
+ builder.addGauge(Interns.info(name + "_mean", desc), convertDuration(snapshot.getMean()));
+ builder.addGauge(Interns.info(name + "_min", desc), convertDuration(snapshot.getMin()));
+ builder.addGauge(Interns.info(name + "_max", desc), convertDuration(snapshot.getMax()));
+ builder.addGauge(Interns.info(name + "_median", desc), convertDuration(snapshot.getMedian()));
+ builder.addGauge(Interns.info(name + "_stddev", desc), convertDuration(snapshot.getStdDev()));
+
+ builder.addGauge(Interns.info(name + "_75thpercentile", desc),
+ convertDuration(snapshot.get75thPercentile()));
+ builder.addGauge(Interns.info(name + "_95thpercentile", desc),
+ convertDuration(snapshot.get95thPercentile()));
+ builder.addGauge(Interns.info(name + "_98thpercentile", desc),
+ convertDuration(snapshot.get98thPercentile()));
+ builder.addGauge(Interns.info(name + "_99thpercentile", desc),
+ convertDuration(snapshot.get99thPercentile()));
+ builder.addGauge(Interns.info(name + "_999thpercentile", desc),
+ convertDuration(snapshot.get999thPercentile()));
+ }
+ @SuppressWarnings("rawtypes")
+ @Override public void report(SortedMap gauges,
+ SortedMap counters, SortedMap histograms,
+ SortedMap meters, SortedMap timers) {
+ for (Entry gauge : gauges.entrySet()) {
+ dropwizardGauges.add(gauge);
+ }
+
+ for (Entry counter : counters.entrySet()) {
+ dropwizardCounters.add(counter);
+ }
+
+ for (Entry histogram : histograms.entrySet()) {
+ dropwizardHistograms.add(histogram);
+ }
+
+ for (Entry meter : meters.entrySet()) {
+ dropwizardMeters.add(meter);
+ }
+
+ for (Entry timer : timers.entrySet()) {
+ dropwizardTimers.add(timer);
+ }
+ }
+
+ @Override protected String getRateUnit() {
+ // Make it "events per rate_unit" to be accurate.
+ return "events/" + super.getRateUnit();
+ }
+
+ @Override protected String getDurationUnit() {
+ // Make it visible to the tests
+ return super.getDurationUnit();
+ }
+
+ @Override protected double convertDuration(double duration) {
+ // Make it visible to the tests
+ return super.convertDuration(duration);
+ }
+
+ @Override protected double convertRate(double rate) {
+ // Make it visible to the tests
+ return super.convertRate(rate);
+ }
+
+ // Getters visible for testing
+
+ MetricsRegistry getMetrics2Registry() {
+ return metrics2Registry;
+ }
+
+ MetricsSystem getMetrics2System() {
+ return metrics2System;
+ }
+
+ String getRecordName() {
+ return recordName;
+ }
+
+ String getContext() {
+ return context;
+ }
+
+ @SuppressWarnings("rawtypes") ConcurrentLinkedQueue> getDropwizardGauges() {
+ return dropwizardGauges;
+ }
+
+ ConcurrentLinkedQueue> getDropwizardCounters() {
+ return dropwizardCounters;
+ }
+
+ ConcurrentLinkedQueue> getDropwizardHistograms() {
+ return dropwizardHistograms;
+ }
+
+ ConcurrentLinkedQueue> getDropwizardMeters() {
+ return dropwizardMeters;
+ }
+
+ ConcurrentLinkedQueue> getDropwizardTimers() {
+ return dropwizardTimers;
+ }
+}
diff --git a/common/src/test/org/apache/hive/common/util/HadoopMetrics2ReporterTest.java b/common/src/test/org/apache/hive/common/util/HadoopMetrics2ReporterTest.java
new file mode 100644
index 0000000..5c6ac99
--- /dev/null
+++ b/common/src/test/org/apache/hive/common/util/HadoopMetrics2ReporterTest.java
@@ -0,0 +1,336 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hive.common.util;
+
+import org.apache.hive.common.util.HadoopMetrics2Reporter;
+import org.apache.hive.common.util.HadoopMetrics2Reporter.Builder;
+
+import com.codahale.metrics.Counter;
+import com.codahale.metrics.Gauge;
+import com.codahale.metrics.Histogram;
+import com.codahale.metrics.Meter;
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.Snapshot;
+import com.codahale.metrics.Timer;
+
+import org.apache.hadoop.metrics2.MetricsCollector;
+import org.apache.hadoop.metrics2.MetricsRecordBuilder;
+import org.apache.hadoop.metrics2.MetricsSystem;
+import org.apache.hadoop.metrics2.lib.Interns;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import java.util.AbstractMap.SimpleEntry;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+/**
+ * Tests for {@link HadoopMetrics2Reporter}.
+ *
+ * Please do not modify, this class is here only temporarily, and is being introduced
+ * in a Deprecated state for
+ */
+@Deprecated
+public class HadoopMetrics2ReporterTest {
+
+ private MetricRegistry mockRegistry;
+ private MetricsSystem mockMetricsSystem;
+ private String recordName = "myserver";
+ private HadoopMetrics2Reporter metrics2Reporter;
+
+ @Before public void setup() {
+ mockRegistry = Mockito.mock(MetricRegistry.class);
+ mockMetricsSystem = Mockito.mock(MetricsSystem.class);
+
+ recordName = "myserver";
+ metrics2Reporter = HadoopMetrics2Reporter.forRegistry(mockRegistry)
+ .convertDurationsTo(TimeUnit.MILLISECONDS)
+ .convertRatesTo(TimeUnit.SECONDS)
+ .build(mockMetricsSystem, "MyServer", "My Cool Server", recordName);
+ }
+
+ private void verifyRecordBuilderUnits(MetricsRecordBuilder recordBuilder) {
+ Mockito.verify(recordBuilder).tag(HadoopMetrics2Reporter.RATE_UNIT_LABEL,
+ metrics2Reporter.getRateUnit());
+ Mockito.verify(recordBuilder).tag(HadoopMetrics2Reporter.DURATION_UNIT_LABEL,
+ metrics2Reporter.getDurationUnit());
+ }
+
+ @Test public void testBuilderDefaults() {
+ Builder builder = HadoopMetrics2Reporter.forRegistry(mockRegistry);
+
+ final String jmxContext = "MyJmxContext;sub=Foo";
+ final String desc = "Description";
+ final String recordName = "Metrics";
+
+ HadoopMetrics2Reporter reporter =
+ builder.build(mockMetricsSystem, jmxContext, desc, recordName);
+
+ assertEquals(mockMetricsSystem, reporter.getMetrics2System());
+ // The Context "tag", not the jmx context
+ assertEquals(null, reporter.getContext());
+ assertEquals(recordName, reporter.getRecordName());
+ }
+
+ @Test public void testGaugeReporting() {
+ final AtomicLong gaugeValue = new AtomicLong(0L);
+ @SuppressWarnings("rawtypes")
+ final Gauge gauge = new Gauge() {
+ @Override public Long getValue() {
+ return gaugeValue.get();
+ }
+ };
+
+ // Add the metrics objects to the internal "queues" by hand
+ metrics2Reporter.getDropwizardGauges().add(new SimpleEntry<>("my_gauge", gauge));
+
+ // Set some values
+ gaugeValue.set(5L);
+
+ MetricsCollector collector = Mockito.mock(MetricsCollector.class);
+ MetricsRecordBuilder recordBuilder = Mockito.mock(MetricsRecordBuilder.class);
+
+ Mockito.when(collector.addRecord(recordName)).thenReturn(recordBuilder);
+
+ // Make sure a value of 5 gets reported
+ metrics2Reporter.getMetrics(collector, true);
+
+ Mockito.verify(recordBuilder).addGauge(Interns.info("my_gauge", ""), gaugeValue.get());
+ verifyRecordBuilderUnits(recordBuilder);
+ }
+
+ @Test public void testCounterReporting() {
+ final Counter counter = new Counter();
+
+ // Add the metrics objects to the internal "queues" by hand
+ metrics2Reporter.getDropwizardCounters().add(new SimpleEntry<>("my_counter", counter));
+
+ // Set some values
+ counter.inc(5L);
+
+ MetricsCollector collector = Mockito.mock(MetricsCollector.class);
+ MetricsRecordBuilder recordBuilder = Mockito.mock(MetricsRecordBuilder.class);
+
+ Mockito.when(collector.addRecord(recordName)).thenReturn(recordBuilder);
+
+ metrics2Reporter.getMetrics(collector, true);
+
+ Mockito.verify(recordBuilder).addCounter(Interns.info("my_counter", ""), 5L);
+ verifyRecordBuilderUnits(recordBuilder);
+ }
+
+ @Test public void testHistogramReporting() {
+ final String metricName = "my_histogram";
+ final Histogram histogram = Mockito.mock(Histogram.class);
+ final Snapshot snapshot = Mockito.mock(Snapshot.class);
+
+ long count = 10L;
+ double percentile75 = 75;
+ double percentile95 = 95;
+ double percentile98 = 98;
+ double percentile99 = 99;
+ double percentile999 = 999;
+ double median = 50;
+ double mean = 60;
+ long min = 1L;
+ long max = 100L;
+ double stddev = 10;
+
+ Mockito.when(snapshot.get75thPercentile()).thenReturn(percentile75);
+ Mockito.when(snapshot.get95thPercentile()).thenReturn(percentile95);
+ Mockito.when(snapshot.get98thPercentile()).thenReturn(percentile98);
+ Mockito.when(snapshot.get99thPercentile()).thenReturn(percentile99);
+ Mockito.when(snapshot.get999thPercentile()).thenReturn(percentile999);
+ Mockito.when(snapshot.getMedian()).thenReturn(median);
+ Mockito.when(snapshot.getMean()).thenReturn(mean);
+ Mockito.when(snapshot.getMin()).thenReturn(min);
+ Mockito.when(snapshot.getMax()).thenReturn(max);
+ Mockito.when(snapshot.getStdDev()).thenReturn(stddev);
+
+ Mockito.when(histogram.getCount()).thenReturn(count);
+ Mockito.when(histogram.getSnapshot()).thenReturn(snapshot);
+
+ MetricsCollector collector = Mockito.mock(MetricsCollector.class);
+ MetricsRecordBuilder recordBuilder = Mockito.mock(MetricsRecordBuilder.class);
+
+ Mockito.when(collector.addRecord(recordName)).thenReturn(recordBuilder);
+
+ // Add the metrics objects to the internal "queues" by hand
+ metrics2Reporter.getDropwizardHistograms().add(new SimpleEntry<>(metricName, histogram));
+
+ metrics2Reporter.getMetrics(collector, true);
+
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_max", ""),
+ metrics2Reporter.convertDuration(max));
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_min", ""),
+ metrics2Reporter.convertDuration(min));
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_median", ""),
+ metrics2Reporter.convertDuration(median));
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_count", ""), count);
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_stddev", ""),
+ metrics2Reporter.convertDuration(stddev));
+
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_75thpercentile", ""),
+ metrics2Reporter.convertDuration(percentile75));
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_95thpercentile", ""),
+ metrics2Reporter.convertDuration(percentile95));
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_98thpercentile", ""),
+ metrics2Reporter.convertDuration(percentile98));
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_99thpercentile", ""),
+ metrics2Reporter.convertDuration(percentile99));
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_999thpercentile", ""),
+ metrics2Reporter.convertDuration(percentile999));
+
+ verifyRecordBuilderUnits(recordBuilder);
+ }
+
+ @Test public void testTimerReporting() {
+ final String metricName = "my_timer";
+ final Timer timer = Mockito.mock(Timer.class);
+ final Snapshot snapshot = Mockito.mock(Snapshot.class);
+
+ // Add the metrics objects to the internal "queues" by hand
+ metrics2Reporter.getDropwizardTimers().add(new SimpleEntry<>(metricName, timer));
+
+ long count = 10L;
+ double meanRate = 1.0;
+ double oneMinRate = 2.0;
+ double fiveMinRate = 5.0;
+ double fifteenMinRate = 10.0;
+
+ Mockito.when(timer.getCount()).thenReturn(count);
+ Mockito.when(timer.getMeanRate()).thenReturn(meanRate);
+ Mockito.when(timer.getOneMinuteRate()).thenReturn(oneMinRate);
+ Mockito.when(timer.getFiveMinuteRate()).thenReturn(fiveMinRate);
+ Mockito.when(timer.getFifteenMinuteRate()).thenReturn(fifteenMinRate);
+ Mockito.when(timer.getSnapshot()).thenReturn(snapshot);
+
+ double percentile75 = 75;
+ double percentile95 = 95;
+ double percentile98 = 98;
+ double percentile99 = 99;
+ double percentile999 = 999;
+ double median = 50;
+ double mean = 60;
+ long min = 1L;
+ long max = 100L;
+ double stddev = 10;
+
+ Mockito.when(snapshot.get75thPercentile()).thenReturn(percentile75);
+ Mockito.when(snapshot.get95thPercentile()).thenReturn(percentile95);
+ Mockito.when(snapshot.get98thPercentile()).thenReturn(percentile98);
+ Mockito.when(snapshot.get99thPercentile()).thenReturn(percentile99);
+ Mockito.when(snapshot.get999thPercentile()).thenReturn(percentile999);
+ Mockito.when(snapshot.getMedian()).thenReturn(median);
+ Mockito.when(snapshot.getMean()).thenReturn(mean);
+ Mockito.when(snapshot.getMin()).thenReturn(min);
+ Mockito.when(snapshot.getMax()).thenReturn(max);
+ Mockito.when(snapshot.getStdDev()).thenReturn(stddev);
+
+ MetricsCollector collector = Mockito.mock(MetricsCollector.class);
+ MetricsRecordBuilder recordBuilder = Mockito.mock(MetricsRecordBuilder.class);
+
+ Mockito.when(collector.addRecord(recordName)).thenReturn(recordBuilder);
+
+ metrics2Reporter.getMetrics(collector, true);
+
+ // We get the count from the meter and histogram
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_count", ""), count);
+
+ // Verify the rates
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_mean_rate", ""),
+ metrics2Reporter.convertRate(meanRate));
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_1min_rate", ""),
+ metrics2Reporter.convertRate(oneMinRate));
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_5min_rate", ""),
+ metrics2Reporter.convertRate(fiveMinRate));
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_15min_rate", ""),
+ metrics2Reporter.convertRate(fifteenMinRate));
+
+ // Verify the histogram
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_max", ""),
+ metrics2Reporter.convertDuration(max));
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_min", ""),
+ metrics2Reporter.convertDuration(min));
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_median", ""),
+ metrics2Reporter.convertDuration(median));
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_stddev", ""),
+ metrics2Reporter.convertDuration(stddev));
+
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_75thpercentile", ""),
+ metrics2Reporter.convertDuration(percentile75));
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_95thpercentile", ""),
+ metrics2Reporter.convertDuration(percentile95));
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_98thpercentile", ""),
+ metrics2Reporter.convertDuration(percentile98));
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_99thpercentile", ""),
+ metrics2Reporter.convertDuration(percentile99));
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_999thpercentile", ""),
+ metrics2Reporter.convertDuration(percentile999));
+
+ verifyRecordBuilderUnits(recordBuilder);
+ }
+
+ @Test public void testMeterReporting() {
+ final String metricName = "my_meter";
+ final Meter meter = Mockito.mock(Meter.class);
+
+ // Add the metrics objects to the internal "queues" by hand
+ metrics2Reporter.getDropwizardMeters().add(new SimpleEntry<>(metricName, meter));
+
+ // Set some values
+ long count = 10L;
+ double meanRate = 1.0;
+ double oneMinRate = 2.0;
+ double fiveMinRate = 5.0;
+ double fifteenMinRate = 10.0;
+
+ Mockito.when(meter.getCount()).thenReturn(count);
+ Mockito.when(meter.getMeanRate()).thenReturn(meanRate);
+ Mockito.when(meter.getOneMinuteRate()).thenReturn(oneMinRate);
+ Mockito.when(meter.getFiveMinuteRate()).thenReturn(fiveMinRate);
+ Mockito.when(meter.getFifteenMinuteRate()).thenReturn(fifteenMinRate);
+
+ MetricsCollector collector = Mockito.mock(MetricsCollector.class);
+ MetricsRecordBuilder recordBuilder = Mockito.mock(MetricsRecordBuilder.class);
+
+ Mockito.when(collector.addRecord(recordName)).thenReturn(recordBuilder);
+
+ metrics2Reporter.getMetrics(collector, true);
+
+ // Verify the rates
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_count", ""), count);
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_mean_rate", ""),
+ metrics2Reporter.convertRate(meanRate));
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_1min_rate", ""),
+ metrics2Reporter.convertRate(oneMinRate));
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_5min_rate", ""),
+ metrics2Reporter.convertRate(fiveMinRate));
+ Mockito.verify(recordBuilder).addGauge(Interns.info(metricName + "_15min_rate", ""),
+ metrics2Reporter.convertRate(fifteenMinRate));
+
+ // Verify the units
+ verifyRecordBuilderUnits(recordBuilder);
+ }
+}