diff options
author | Mayur Kale <mayurkale@google.com> | 2018-10-08 14:25:01 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-08 14:25:01 -0700 |
commit | 08d09c48a40b7dc6b5dba8603795084fc6ea9695 (patch) | |
tree | 72575bc80056208a36ccb362c94abe7c71dc4312 | |
parent | 90edbd5a8a0ff10d7658bd78beae9434aee8cdbe (diff) | |
download | opencensus-java-08d09c48a40b7dc6b5dba8603795084fc6ea9695.tar.gz |
Add dropwizard contrib (#1423)
* Add dropwizard metrics producer
* Use Summary Type
* Fix reviews
* Fix reviews
-rw-r--r-- | all/build.gradle | 2 | ||||
-rw-r--r-- | build.gradle | 3 | ||||
-rw-r--r-- | buildscripts/import-control.xml | 7 | ||||
-rw-r--r-- | contrib/dropwizard/README.md | 120 | ||||
-rw-r--r-- | contrib/dropwizard/build.gradle | 17 | ||||
-rw-r--r-- | contrib/dropwizard/src/main/java/io/opencensus/contrib/dropwizard/DropWizardMetrics.java | 330 | ||||
-rw-r--r-- | contrib/dropwizard/src/main/java/io/opencensus/contrib/dropwizard/DropWizardUtils.java | 55 | ||||
-rw-r--r-- | contrib/dropwizard/src/test/java/io/opencensus/contrib/dropwizard/DropWizardMetricsTest.java | 344 | ||||
-rw-r--r-- | contrib/dropwizard/src/test/java/io/opencensus/contrib/dropwizard/DropWizardUtilsTest.java | 41 | ||||
-rw-r--r-- | settings.gradle | 2 |
10 files changed, 921 insertions, 0 deletions
diff --git a/all/build.gradle b/all/build.gradle index e3a0c4c6..83ffb69e 100644 --- a/all/build.gradle +++ b/all/build.gradle @@ -8,6 +8,7 @@ def subprojects = [ project(':opencensus-testing'), project(':opencensus-contrib-agent'), project(':opencensus-contrib-appengine-standard-util'), + project(':opencensus-contrib-dropwizard'), project(':opencensus-contrib-exemplar-util'), project(':opencensus-contrib-grpc-util'), project(':opencensus-contrib-grpc-metrics'), @@ -34,6 +35,7 @@ def subprojects_javadoc = [ project(':opencensus-testing'), project(':opencensus-contrib-agent'), project(':opencensus-contrib-appengine-standard-util'), + project(':opencensus-contrib-dropwizard'), project(':opencensus-contrib-exemplar-util'), project(':opencensus-contrib-grpc-util'), project(':opencensus-contrib-grpc-metrics'), diff --git a/build.gradle b/build.gradle index 9ecd7b90..abf2413b 100644 --- a/build.gradle +++ b/build.gradle @@ -168,6 +168,7 @@ subprojects { zipkinReporterVersion = '2.3.2' jaegerReporterVersion = '0.27.0' opencensusProtoVersion = '0.0.2' + dropwizardVersion = '3.1.2' libraries = [ appengine_api: "com.google.appengine:appengine-api-1.0-sdk:${appengineVersion}", @@ -208,6 +209,7 @@ subprojects { mockito: 'org.mockito:mockito-core:1.9.5', spring_test: "org.springframework:spring-test:${springVersion}", truth: 'com.google.truth:truth:0.30', + dropwizard: "io.dropwizard.metrics:metrics-core:${dropwizardVersion}", ] } @@ -416,6 +418,7 @@ subprojects { name in ['opencensus-api', 'opencensus-contrib-agent', 'opencensus-contrib-appengine-standard-util', + 'opencensus-contrib-dropwizard', 'opencensus-contrib-exemplar-util', 'opencensus-contrib-grpc-metrics', 'opencensus-contrib-grpc-util', diff --git a/buildscripts/import-control.xml b/buildscripts/import-control.xml index 002820d8..be93cd9e 100644 --- a/buildscripts/import-control.xml +++ b/buildscripts/import-control.xml @@ -134,6 +134,13 @@ General guidelines on imports: <subpackage name="monitoredresource.util"> <allow pkg="io.opencensus.contrib.monitoredresource.util"/> </subpackage> + <subpackage name="dropwizard"> + <allow pkg="io.opencensus.contrib.dropwizard"/> + <allow pkg="io.opencensus.metrics"/> + <allow pkg="io.opencensus.implcore"/> + <allow pkg="io.opencensus.internal"/> + <allow pkg="com.codahale.metrics"/> + </subpackage> </subpackage> <subpackage name="exporter"> <allow pkg="com.google.common"/> diff --git a/contrib/dropwizard/README.md b/contrib/dropwizard/README.md new file mode 100644 index 00000000..395c303f --- /dev/null +++ b/contrib/dropwizard/README.md @@ -0,0 +1,120 @@ +# OpenCensus DropWizard Util for Java + +The *OpenCensus DropWizard Util for Java* provides an easy way to translate Dropwizard metrics to +OpenCensus. + +## Quickstart + +### Prerequisites + +Assuming, you already have both the OpenCensus and Dropwizard client libraries setup and working +inside your application. + +### Add the dependencies to your project + +For Maven add to your `pom.xml`: +```xml +<dependencies> + <dependency> + <groupId>io.opencensus</groupId> + <artifactId>opencensus-contrib-dropwizard</artifactId> + <version>0.17.0</version> + </dependency> +</dependencies> +``` + +For Gradle add to your dependencies: +```gradle +compile 'io.opencensus:opencensus-dropwizard:0.17.0' +``` + +### And the following code: + +```java +import java.util.Collections; + +public class YourClass { + // Create registry for Dropwizard metrics. + static final com.codahale.metrics.MetricRegistry codahaleRegistry = + new com.codahale.metrics.MetricRegistry(); + + // Create a Dropwizard counter. + static final com.codahale.metrics.Counter requests = codahaleRegistry.counter("requests"); + + public static void main(String[] args) { + + // Increment the requests. + requests.inc(); + + // Hook the Dropwizard registry into the OpenCensus registry + // via the DropWizardMetrics metric producer. + io.opencensus.metrics.Metrics.getExportComponent().getMetricProducerManager().add( + new io.opencensus.contrib.dropwizard.DropWizardMetrics( + Collections.singletonList(codahaleRegistry))); + + } +} +``` + +## Translation to OpenCensus Metrics + +This section describes how each of the DropWizard metrics translate into OpenCensus metrics. + +### DropWizard Counters + +Given a DropWizard Counter with name `cache_evictions`, the following values are reported: + +* name: codahale_<initial_metric_name>_<initial_type> (ex: codahale_cache_evictions_counter) +* description: Collected from Dropwizard (metric=<metric_name>, type=<class_name>) +(ex: Collected from Dropwizard (metric=cache_evictions, type=com.codahale.metrics.Counter)) +* type: GAUGE_INT64 +* unit: 1 + +Note: OpenCensus's CUMULATIVE_INT64 type represent monotonically increasing values. Since +DropWizard Counter goes up/down, it make sense to report them as OpenCensus GAUGE_INT64. + +### DropWizard Gauges + +Given a DropWizard Gauge with name `line_requests`, the following values are reported: + +* name: codahale_<initial_metric_name>_<initial_type> (ex: codahale_line_requests_gauge) +* description: Collected from Dropwizard (metric=<metric_name>, type=<class_name>) +* type: GAUGE_INT64 or GAUGE_DOUBLE +* unit: 1 + +Note: For simplicity, OpenCensus uses GAUGE_DOUBLE type for any Number and GAUGE_INT64 +type for Boolean values. + +### DropWizard Meters + +Given a DropWizard Meter with name `get_requests`, the following values are reported: + +* name: codahale_<initial_metric_name>_<initial_type> (ex: codahale_get_requests_meter) +* description: Collected from Dropwizard (metric=<metric_name>, type=<class_name>) +* type: CUMULATIVE_INT64 +* unit: 1 + +rate metrics: +* name: codahale_<initial_metric_name>_<initial_type> (ex: codahale_get_requests_meter_rate) +* description: Collected from Dropwizard (metric=<metric_name>, type=<class_name>) +* type: GAUGE_DOUBLE +* unit: "events/second" +* labelkeys: rate (with 4 TimeSeries, one corresponding to each rate: mean_rate, m1_rate, +m5_rate m15_rate) + +### DropWizard Histograms + +Given a DropWizard Histogram with name `results`, the following values are reported: + +* name: codahale_<initial_metric_name>_<initial_type> (ex: codahale_results_histogram) +* description: Collected from Dropwizard (metric=<metric_name>, type=<class_name>) +* type: SUMMARY +* unit: 1 + +### DropWizard Timers + +Given a DropWizard Timer with name `requests`, the following values are reported: +* name: codahale_<initial_metric_name>_<initial_type> (ex: codahale_requests_timer) +* description: Collected from Dropwizard (metric=<metric_name>, type=<class_name>) +* type: SUMMARY +* unit: 1 diff --git a/contrib/dropwizard/build.gradle b/contrib/dropwizard/build.gradle new file mode 100644 index 00000000..7da41cbe --- /dev/null +++ b/contrib/dropwizard/build.gradle @@ -0,0 +1,17 @@ +description = 'OpenCensus dropwizard util' + +apply plugin: 'java' + +[compileJava, compileTestJava].each() { + it.sourceCompatibility = 1.7 + it.targetCompatibility = 1.7 +} + +dependencies { + compile project(':opencensus-api'), + project(':opencensus-impl-core') + + compile libraries.dropwizard + + signature "org.codehaus.mojo.signature:java17:1.0@signature" +} diff --git a/contrib/dropwizard/src/main/java/io/opencensus/contrib/dropwizard/DropWizardMetrics.java b/contrib/dropwizard/src/main/java/io/opencensus/contrib/dropwizard/DropWizardMetrics.java new file mode 100644 index 00000000..7cc52d3f --- /dev/null +++ b/contrib/dropwizard/src/main/java/io/opencensus/contrib/dropwizard/DropWizardMetrics.java @@ -0,0 +1,330 @@ +/* + * Copyright 2018, OpenCensus Authors + * + * Licensed 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 io.opencensus.contrib.dropwizard; + +import com.codahale.metrics.Counter; +import com.codahale.metrics.Gauge; +import com.codahale.metrics.Histogram; +import com.codahale.metrics.Meter; +import com.codahale.metrics.Timer; +import io.opencensus.common.Clock; +import io.opencensus.common.Timestamp; +import io.opencensus.implcore.common.MillisClock; +import io.opencensus.internal.DefaultVisibilityForTesting; +import io.opencensus.internal.Utils; +import io.opencensus.metrics.LabelKey; +import io.opencensus.metrics.LabelValue; +import io.opencensus.metrics.export.Metric; +import io.opencensus.metrics.export.MetricDescriptor; +import io.opencensus.metrics.export.MetricDescriptor.Type; +import io.opencensus.metrics.export.MetricProducer; +import io.opencensus.metrics.export.Point; +import io.opencensus.metrics.export.Summary; +import io.opencensus.metrics.export.Summary.Snapshot; +import io.opencensus.metrics.export.Summary.Snapshot.ValueAtPercentile; +import io.opencensus.metrics.export.TimeSeries; +import io.opencensus.metrics.export.Value; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map.Entry; +import javax.annotation.Nullable; + +/** + * Collects DropWizard metrics from a list {@link com.codahale.metrics.MetricRegistry}s. + * + * <p>A {@link io.opencensus.metrics.export.MetricProducer} that wraps a DropWizardMetrics. + * + * @since 0.17 + */ +public class DropWizardMetrics extends MetricProducer { + + @DefaultVisibilityForTesting static final String DEFAULT_UNIT = "1"; + + @DefaultVisibilityForTesting + static final List<LabelKey> RATE_LABEL_KEY = + Collections.singletonList(LabelKey.create("rate", "measures the rate of events over time")); + + @DefaultVisibilityForTesting + static final List<LabelValue> RATE_MEAN_LABEL_VALUE = + Collections.singletonList(LabelValue.create("mean_rate")); + + @DefaultVisibilityForTesting + static final List<LabelValue> RATE_ONE_MINUTE_LABEL_VALUE = + Collections.singletonList(LabelValue.create("m1_rate")); + + @DefaultVisibilityForTesting + static final List<LabelValue> RATE_FIVE_MINUTE_LABEL_VALUE = + Collections.singletonList(LabelValue.create("m5_rate")); + + @DefaultVisibilityForTesting + static final List<LabelValue> RATE_FIFTEEN_MINUTE_LABEL_VALUE = + Collections.singletonList(LabelValue.create("m15_rate")); + + private final List<com.codahale.metrics.MetricRegistry> metricRegistryList; + private final Clock clock; + private final Timestamp cumulativeStartTimestamp; + + /** + * Hook the Dropwizard registry into the OpenCensus registry. + * + * @param metricRegistryList a list of {@link com.codahale.metrics.MetricRegistry}s. + * @since 0.17 + */ + public DropWizardMetrics(List<com.codahale.metrics.MetricRegistry> metricRegistryList) { + Utils.checkNotNull(metricRegistryList, "metricRegistryList"); + Utils.checkListElementNotNull(metricRegistryList, "metricRegistryList"); + this.metricRegistryList = metricRegistryList; + clock = MillisClock.getInstance(); + cumulativeStartTimestamp = clock.now(); + } + + /** + * Returns a {@code Metric} collected from {@link Gauge}. + * + * @param dropwizardName the metric name. + * @param gauge the gauge object to collect. + * @return a {@code Metric}. + */ + @SuppressWarnings("rawtypes") + private @Nullable Metric collectGauge(String dropwizardName, Gauge gauge) { + String metricName = DropWizardUtils.generateFullMetricName(dropwizardName, "gauge"); + String metricDescription = DropWizardUtils.generateFullMetricDescription(dropwizardName, gauge); + + // Figure out which gauge instance and call the right method to get value + Type type; + Value value; + + Object obj = gauge.getValue(); + if (obj instanceof Number) { + type = Type.GAUGE_DOUBLE; + value = Value.doubleValue(((Number) obj).doubleValue()); + } else if (obj instanceof Boolean) { + type = Type.GAUGE_INT64; + value = Value.longValue(((Boolean) obj) ? 1 : 0); + } else { + // Ignoring Gauge (gauge.getKey()) with unhandled type. + return null; + } + + MetricDescriptor metricDescriptor = + MetricDescriptor.create( + metricName, metricDescription, DEFAULT_UNIT, type, Collections.<LabelKey>emptyList()); + TimeSeries timeSeries = + TimeSeries.create( + Collections.<LabelValue>emptyList(), + Collections.singletonList(Point.create(value, clock.now())), + null); + return Metric.create(metricDescriptor, Collections.singletonList(timeSeries)); + } + + /** + * Returns a {@code Metric} collected from {@link Counter}. + * + * @param dropwizardName the metric name. + * @param counter the counter object to collect. + * @return a {@code Metric}. + */ + private Metric collectCounter(String dropwizardName, Counter counter) { + String metricName = DropWizardUtils.generateFullMetricName(dropwizardName, "counter"); + String metricDescription = + DropWizardUtils.generateFullMetricDescription(dropwizardName, counter); + + MetricDescriptor metricDescriptor = + MetricDescriptor.create( + metricName, + metricDescription, + DEFAULT_UNIT, + Type.GAUGE_INT64, + Collections.<LabelKey>emptyList()); + TimeSeries timeSeries = + TimeSeries.create( + Collections.<LabelValue>emptyList(), + Collections.singletonList( + Point.create(Value.longValue(counter.getCount()), clock.now())), + null); + return Metric.create(metricDescriptor, Collections.singletonList(timeSeries)); + } + + /** + * Returns a list of {@link Metric}s collected from {@link Meter}. + * + * @param dropwizardName the metric name. + * @param meter the meter object to collect + * @return a list of {@link Metric}s. + */ + private List<Metric> collectMeter(String dropwizardName, Meter meter) { + String metricName = DropWizardUtils.generateFullMetricName(dropwizardName, "meter"); + String metricDescription = DropWizardUtils.generateFullMetricDescription(dropwizardName, meter); + + MetricDescriptor countMetricDescriptor = + MetricDescriptor.create( + metricName, + metricDescription, + DEFAULT_UNIT, + Type.CUMULATIVE_INT64, + Collections.<LabelKey>emptyList()); + TimeSeries countTimeSeries = + TimeSeries.create( + Collections.<LabelValue>emptyList(), + Collections.singletonList(Point.create(Value.longValue(meter.getCount()), clock.now())), + null); + + // Collect rate related metric + metricName = DropWizardUtils.generateFullMetricName(dropwizardName, "meter_rate"); + metricDescription = DropWizardUtils.generateFullMetricDescription(dropwizardName, meter); + + MetricDescriptor rateMetricDescriptor = + MetricDescriptor.create( + metricName, metricDescription, "events/second", Type.GAUGE_DOUBLE, RATE_LABEL_KEY); + + List<TimeSeries> timeSeriesList = + Arrays.asList( + TimeSeries.create( + RATE_MEAN_LABEL_VALUE, + Collections.singletonList( + Point.create(Value.doubleValue(meter.getMeanRate()), clock.now())), + null), + TimeSeries.create( + RATE_ONE_MINUTE_LABEL_VALUE, + Collections.singletonList( + Point.create(Value.doubleValue(meter.getOneMinuteRate()), clock.now())), + null), + TimeSeries.create( + RATE_FIVE_MINUTE_LABEL_VALUE, + Collections.singletonList( + Point.create(Value.doubleValue(meter.getFiveMinuteRate()), clock.now())), + null), + TimeSeries.create( + RATE_FIFTEEN_MINUTE_LABEL_VALUE, + Collections.singletonList( + Point.create(Value.doubleValue(meter.getFifteenMinuteRate()), clock.now())), + null)); + + return Collections.unmodifiableList( + Arrays.asList( + Metric.create(countMetricDescriptor, Collections.singletonList(countTimeSeries)), + Metric.create(rateMetricDescriptor, Collections.unmodifiableList(timeSeriesList)))); + } + + /** + * Returns a {@code Metric} collected from {@link Histogram}. + * + * @param dropwizardName the metric name. + * @param histogram the histogram object to collect + * @return a {@code Metric}. + */ + private Metric collectHistogram(String dropwizardName, Histogram histogram) { + String metricName = DropWizardUtils.generateFullMetricName(dropwizardName, "histogram"); + String metricDescription = + DropWizardUtils.generateFullMetricDescription(dropwizardName, histogram); + return collectSnapshotAndCount( + metricName, metricDescription, histogram.getSnapshot(), histogram.getCount()); + } + + /** + * Returns a {@code Metric} collected from {@link Timer}. + * + * @param dropwizardName the metric name. + * @param timer the timer object to collect + * @return a {@code Metric}. + */ + private Metric collectTimer(String dropwizardName, Timer timer) { + String metricName = DropWizardUtils.generateFullMetricName(dropwizardName, "timer"); + String metricDescription = DropWizardUtils.generateFullMetricDescription(dropwizardName, timer); + return collectSnapshotAndCount( + metricName, metricDescription, timer.getSnapshot(), timer.getCount()); + } + + /** + * Returns a {@code Metric} collected from {@link Snapshot}. + * + * @param metricName the metric name. + * @param metricDescription the metric description. + * @param codahaleSnapshot the snapshot object to collect + * @param count the value or count + * @return a {@code Metric}. + */ + private Metric collectSnapshotAndCount( + String metricName, + String metricDescription, + com.codahale.metrics.Snapshot codahaleSnapshot, + long count) { + List<ValueAtPercentile> valueAtPercentiles = + Arrays.asList( + ValueAtPercentile.create(50.0, codahaleSnapshot.getMedian()), + ValueAtPercentile.create(75.0, codahaleSnapshot.get75thPercentile()), + ValueAtPercentile.create(98.0, codahaleSnapshot.get98thPercentile()), + ValueAtPercentile.create(99.0, codahaleSnapshot.get99thPercentile()), + ValueAtPercentile.create(99.9, codahaleSnapshot.get999thPercentile())); + + Snapshot snapshot = Snapshot.create((long) codahaleSnapshot.size(), 0.0, valueAtPercentiles); + Point point = + Point.create(Value.summaryValue(Summary.create(count, 0.0, snapshot)), clock.now()); + + // TODO(mayurkale): OPTIMIZATION: Cache the MetricDescriptor objects. + MetricDescriptor metricDescriptor = + MetricDescriptor.create( + metricName, + metricDescription, + DEFAULT_UNIT, + Type.SUMMARY, + Collections.<LabelKey>emptyList()); + TimeSeries timeSeries = + TimeSeries.create( + Collections.<LabelValue>emptyList(), + Collections.singletonList(point), + cumulativeStartTimestamp); + + return Metric.create(metricDescriptor, Collections.singletonList(timeSeries)); + } + + @Override + @SuppressWarnings("rawtypes") + public Collection<Metric> getMetrics() { + ArrayList<Metric> metrics = new ArrayList<Metric>(); + + for (com.codahale.metrics.MetricRegistry metricRegistry : metricRegistryList) { + for (Entry<String, Counter> counterEntry : metricRegistry.getCounters().entrySet()) { + metrics.add(collectCounter(counterEntry.getKey(), counterEntry.getValue())); + } + + for (Entry<String, Gauge> gaugeEntry : metricRegistry.getGauges().entrySet()) { + Metric metric = collectGauge(gaugeEntry.getKey(), gaugeEntry.getValue()); + if (metric != null) { + metrics.add(metric); + } + } + + for (Entry<String, Meter> counterEntry : metricRegistry.getMeters().entrySet()) { + metrics.addAll(collectMeter(counterEntry.getKey(), counterEntry.getValue())); + } + + for (Entry<String, Histogram> counterEntry : metricRegistry.getHistograms().entrySet()) { + metrics.add(collectHistogram(counterEntry.getKey(), counterEntry.getValue())); + } + + for (Entry<String, Timer> counterEntry : metricRegistry.getTimers().entrySet()) { + metrics.add(collectTimer(counterEntry.getKey(), counterEntry.getValue())); + } + } + + return metrics; + } +} diff --git a/contrib/dropwizard/src/main/java/io/opencensus/contrib/dropwizard/DropWizardUtils.java b/contrib/dropwizard/src/main/java/io/opencensus/contrib/dropwizard/DropWizardUtils.java new file mode 100644 index 00000000..372e5c60 --- /dev/null +++ b/contrib/dropwizard/src/main/java/io/opencensus/contrib/dropwizard/DropWizardUtils.java @@ -0,0 +1,55 @@ +/* + * Copyright 2018, OpenCensus Authors + * + * Licensed 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 io.opencensus.contrib.dropwizard; + +import com.codahale.metrics.Metric; + +/** Util methods for generating the metric name(unique) and description. */ +final class DropWizardUtils { + private static final String SOURCE = "codahale"; + private static final char DELIMITER = '_'; + + /** + * Returns the metric name. + * + * @param name the initial metric name + * @param type the initial type of the metric. + * @return a string the unique metric name + */ + static String generateFullMetricName(String name, String type) { + return SOURCE + DELIMITER + name + DELIMITER + type; + } + + /** + * Returns the metric description. + * + * @param metricName the initial metric name + * @param metric the codahale metric class. + * @return a String the custom metric description + */ + static String generateFullMetricDescription(String metricName, Metric metric) { + return "Collected from " + + SOURCE + + " (metric=" + + metricName + + ", type=" + + metric.getClass().getName() + + ")"; + } + + private DropWizardUtils() {} +} diff --git a/contrib/dropwizard/src/test/java/io/opencensus/contrib/dropwizard/DropWizardMetricsTest.java b/contrib/dropwizard/src/test/java/io/opencensus/contrib/dropwizard/DropWizardMetricsTest.java new file mode 100644 index 00000000..f7304ceb --- /dev/null +++ b/contrib/dropwizard/src/test/java/io/opencensus/contrib/dropwizard/DropWizardMetricsTest.java @@ -0,0 +1,344 @@ +/* + * Copyright 2018, OpenCensus Authors + * + * Licensed 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 io.opencensus.contrib.dropwizard; + +import static com.google.common.truth.Truth.assertThat; +import static io.opencensus.contrib.dropwizard.DropWizardMetrics.DEFAULT_UNIT; +import static io.opencensus.contrib.dropwizard.DropWizardMetrics.RATE_FIFTEEN_MINUTE_LABEL_VALUE; +import static io.opencensus.contrib.dropwizard.DropWizardMetrics.RATE_FIVE_MINUTE_LABEL_VALUE; +import static io.opencensus.contrib.dropwizard.DropWizardMetrics.RATE_LABEL_KEY; +import static io.opencensus.contrib.dropwizard.DropWizardMetrics.RATE_MEAN_LABEL_VALUE; +import static io.opencensus.contrib.dropwizard.DropWizardMetrics.RATE_ONE_MINUTE_LABEL_VALUE; + +import com.codahale.metrics.Counter; +import com.codahale.metrics.Gauge; +import com.codahale.metrics.Histogram; +import com.codahale.metrics.Meter; +import com.codahale.metrics.Timer; +import io.opencensus.common.Timestamp; +import io.opencensus.metrics.LabelKey; +import io.opencensus.metrics.export.Metric; +import io.opencensus.metrics.export.MetricDescriptor; +import io.opencensus.metrics.export.MetricDescriptor.Type; +import io.opencensus.metrics.export.Summary; +import io.opencensus.metrics.export.Summary.Snapshot; +import io.opencensus.metrics.export.Summary.Snapshot.ValueAtPercentile; +import io.opencensus.metrics.export.Value; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link DropWizardMetrics}. */ +@RunWith(JUnit4.class) +public class DropWizardMetricsTest { + + private com.codahale.metrics.MetricRegistry metricRegistry; + DropWizardMetrics dropWizardMetrics; + + @Before + public void setUp() throws Exception { + metricRegistry = new com.codahale.metrics.MetricRegistry(); + dropWizardMetrics = new DropWizardMetrics(Collections.singletonList((metricRegistry))); + } + + @Test + public void collect() throws InterruptedException { + + // create dropwizard metrics + Counter evictions = metricRegistry.counter("cache_evictions"); + evictions.inc(); + evictions.inc(3); + evictions.dec(); + evictions.dec(2); + + Gauge<Integer> integerGauge = + new Gauge<Integer>() { + @Override + public Integer getValue() { + return 1234; + } + }; + metricRegistry.register("integer_gauge", integerGauge); + + Gauge<Double> doubleGauge = + new Gauge<Double>() { + @Override + public Double getValue() { + return 1.234D; + } + }; + metricRegistry.register("double_gauge", doubleGauge); + + Gauge<Long> longGauge = + new Gauge<Long>() { + @Override + public Long getValue() { + return 1234L; + } + }; + metricRegistry.register("long_gauge", longGauge); + + Gauge<Float> floatGauge = + new Gauge<Float>() { + @Override + public Float getValue() { + return 0.1234F; + } + }; + metricRegistry.register("float_gauge", floatGauge); + + Gauge<Boolean> boolGauge = + new Gauge<Boolean>() { + @Override + public Boolean getValue() { + return Boolean.TRUE; + } + }; + metricRegistry.register("boolean_gauge", boolGauge); + + Meter getRequests = metricRegistry.meter("get_requests"); + getRequests.mark(); + getRequests.mark(); + + Histogram resultCounts = metricRegistry.histogram("result"); + resultCounts.update(200); + + Timer timer = metricRegistry.timer("requests"); + Timer.Context context = timer.time(); + Thread.sleep(1L); + context.stop(); + + ArrayList<Metric> metrics = new ArrayList<Metric>(dropWizardMetrics.getMetrics()); + assertThat(metrics.size()).isEqualTo(10); + + assertThat(metrics.get(0).getMetricDescriptor()) + .isEqualTo( + MetricDescriptor.create( + "codahale_cache_evictions_counter", + "Collected from codahale (metric=cache_evictions, " + + "type=com.codahale.metrics.Counter)", + DEFAULT_UNIT, + Type.GAUGE_INT64, + Collections.<LabelKey>emptyList())); + assertThat(metrics.get(0).getTimeSeriesList().size()).isEqualTo(1); + assertThat(metrics.get(0).getTimeSeriesList().get(0).getLabelValues().size()).isEqualTo(0); + assertThat(metrics.get(0).getTimeSeriesList().get(0).getPoints().size()).isEqualTo(1); + assertThat(metrics.get(0).getTimeSeriesList().get(0).getPoints().get(0).getValue()) + .isEqualTo(Value.longValue(1)); + assertThat(metrics.get(0).getTimeSeriesList().get(0).getStartTimestamp()).isEqualTo(null); + + assertThat(metrics.get(1).getMetricDescriptor()) + .isEqualTo( + MetricDescriptor.create( + "codahale_boolean_gauge_gauge", + "Collected from codahale (metric=boolean_gauge, " + + "type=io.opencensus.contrib.dropwizard.DropWizardMetricsTest$5)", + DEFAULT_UNIT, + Type.GAUGE_INT64, + Collections.<LabelKey>emptyList())); + assertThat(metrics.get(1).getTimeSeriesList().size()).isEqualTo(1); + assertThat(metrics.get(1).getTimeSeriesList().get(0).getLabelValues().size()).isEqualTo(0); + assertThat(metrics.get(1).getTimeSeriesList().get(0).getPoints().size()).isEqualTo(1); + assertThat(metrics.get(1).getTimeSeriesList().get(0).getPoints().get(0).getValue()) + .isEqualTo(Value.longValue(1)); + assertThat(metrics.get(1).getTimeSeriesList().get(0).getStartTimestamp()).isEqualTo(null); + + assertThat(metrics.get(2).getMetricDescriptor()) + .isEqualTo( + MetricDescriptor.create( + "codahale_double_gauge_gauge", + "Collected from codahale (metric=double_gauge, " + + "type=io.opencensus.contrib.dropwizard.DropWizardMetricsTest$2)", + DEFAULT_UNIT, + Type.GAUGE_DOUBLE, + Collections.<LabelKey>emptyList())); + assertThat(metrics.get(2).getTimeSeriesList().size()).isEqualTo(1); + assertThat(metrics.get(2).getTimeSeriesList().get(0).getLabelValues().size()).isEqualTo(0); + assertThat(metrics.get(2).getTimeSeriesList().get(0).getPoints().size()).isEqualTo(1); + assertThat(metrics.get(2).getTimeSeriesList().get(0).getPoints().get(0).getValue()) + .isEqualTo(Value.doubleValue(1.234)); + assertThat(metrics.get(2).getTimeSeriesList().get(0).getStartTimestamp()).isEqualTo(null); + + assertThat(metrics.get(3).getMetricDescriptor()) + .isEqualTo( + MetricDescriptor.create( + "codahale_float_gauge_gauge", + "Collected from codahale (metric=float_gauge, " + + "type=io.opencensus.contrib.dropwizard.DropWizardMetricsTest$4)", + DEFAULT_UNIT, + Type.GAUGE_DOUBLE, + Collections.<LabelKey>emptyList())); + assertThat(metrics.get(3).getTimeSeriesList().size()).isEqualTo(1); + assertThat(metrics.get(3).getTimeSeriesList().get(0).getLabelValues().size()).isEqualTo(0); + assertThat(metrics.get(3).getTimeSeriesList().get(0).getPoints().size()).isEqualTo(1); + assertThat(metrics.get(3).getTimeSeriesList().get(0).getPoints().get(0).getValue()) + .isEqualTo(Value.doubleValue(0.1234000027179718)); + assertThat(metrics.get(3).getTimeSeriesList().get(0).getStartTimestamp()).isEqualTo(null); + + assertThat(metrics.get(4).getMetricDescriptor()) + .isEqualTo( + MetricDescriptor.create( + "codahale_integer_gauge_gauge", + "Collected from codahale (metric=integer_gauge, " + + "type=io.opencensus.contrib.dropwizard.DropWizardMetricsTest$1)", + DEFAULT_UNIT, + Type.GAUGE_DOUBLE, + Collections.<LabelKey>emptyList())); + assertThat(metrics.get(4).getTimeSeriesList().size()).isEqualTo(1); + assertThat(metrics.get(4).getTimeSeriesList().get(0).getLabelValues().size()).isEqualTo(0); + assertThat(metrics.get(4).getTimeSeriesList().get(0).getPoints().size()).isEqualTo(1); + assertThat(metrics.get(4).getTimeSeriesList().get(0).getPoints().get(0).getValue()) + .isEqualTo(Value.doubleValue(1234.0)); + assertThat(metrics.get(4).getTimeSeriesList().get(0).getStartTimestamp()).isEqualTo(null); + + assertThat(metrics.get(5).getMetricDescriptor()) + .isEqualTo( + MetricDescriptor.create( + "codahale_long_gauge_gauge", + "Collected from codahale (metric=long_gauge, " + + "type=io.opencensus.contrib.dropwizard.DropWizardMetricsTest$3)", + DEFAULT_UNIT, + Type.GAUGE_DOUBLE, + Collections.<LabelKey>emptyList())); + assertThat(metrics.get(5).getTimeSeriesList().size()).isEqualTo(1); + assertThat(metrics.get(5).getTimeSeriesList().get(0).getLabelValues().size()).isEqualTo(0); + assertThat(metrics.get(5).getTimeSeriesList().get(0).getPoints().size()).isEqualTo(1); + assertThat(metrics.get(5).getTimeSeriesList().get(0).getPoints().get(0).getValue()) + .isEqualTo(Value.doubleValue(1234.0)); + assertThat(metrics.get(5).getTimeSeriesList().get(0).getStartTimestamp()).isEqualTo(null); + + assertThat(metrics.get(6).getMetricDescriptor()) + .isEqualTo( + MetricDescriptor.create( + "codahale_get_requests_meter", + "Collected from codahale (metric=get_requests, " + + "type=com.codahale.metrics.Meter)", + DEFAULT_UNIT, + Type.CUMULATIVE_INT64, + Collections.<LabelKey>emptyList())); + assertThat(metrics.get(6).getTimeSeriesList().size()).isEqualTo(1); + assertThat(metrics.get(6).getTimeSeriesList().get(0).getLabelValues().size()).isEqualTo(0); + assertThat(metrics.get(6).getTimeSeriesList().get(0).getPoints().size()).isEqualTo(1); + assertThat(metrics.get(6).getTimeSeriesList().get(0).getPoints().get(0).getValue()) + .isEqualTo(Value.longValue(2)); + assertThat(metrics.get(6).getTimeSeriesList().get(0).getStartTimestamp()).isEqualTo(null); + + assertThat(metrics.get(7).getMetricDescriptor()) + .isEqualTo( + MetricDescriptor.create( + "codahale_get_requests_meter_rate", + "Collected from codahale (metric=get_requests, " + + "type=com.codahale.metrics.Meter)", + "events/second", + Type.GAUGE_DOUBLE, + RATE_LABEL_KEY)); + assertThat(metrics.get(7).getTimeSeriesList().size()).isEqualTo(4); + assertThat(metrics.get(7).getTimeSeriesList().get(0).getLabelValues().size()).isEqualTo(1); + assertThat(metrics.get(7).getTimeSeriesList().get(0).getLabelValues()) + .isEqualTo(RATE_MEAN_LABEL_VALUE); + assertThat(metrics.get(7).getTimeSeriesList().get(0).getPoints().size()).isEqualTo(1); + assertThat(metrics.get(7).getTimeSeriesList().get(0).getPoints()).isNotEmpty(); + assertThat(metrics.get(7).getTimeSeriesList().get(0).getStartTimestamp()).isEqualTo(null); + + assertThat(metrics.get(7).getTimeSeriesList().get(1).getLabelValues()) + .isEqualTo(RATE_ONE_MINUTE_LABEL_VALUE); + assertThat(metrics.get(7).getTimeSeriesList().get(1).getPoints().size()).isEqualTo(1); + assertThat(metrics.get(7).getTimeSeriesList().get(1).getPoints()).isNotEmpty(); + assertThat(metrics.get(7).getTimeSeriesList().get(1).getStartTimestamp()).isEqualTo(null); + + assertThat(metrics.get(7).getTimeSeriesList().get(2).getLabelValues()) + .isEqualTo(RATE_FIVE_MINUTE_LABEL_VALUE); + assertThat(metrics.get(7).getTimeSeriesList().get(2).getPoints().size()).isEqualTo(1); + assertThat(metrics.get(7).getTimeSeriesList().get(2).getPoints()).isNotEmpty(); + assertThat(metrics.get(7).getTimeSeriesList().get(2).getStartTimestamp()).isEqualTo(null); + + assertThat(metrics.get(7).getTimeSeriesList().get(3).getLabelValues()) + .isEqualTo(RATE_FIFTEEN_MINUTE_LABEL_VALUE); + assertThat(metrics.get(7).getTimeSeriesList().get(3).getPoints().size()).isEqualTo(1); + assertThat(metrics.get(7).getTimeSeriesList().get(3).getPoints()).isNotEmpty(); + assertThat(metrics.get(7).getTimeSeriesList().get(3).getStartTimestamp()).isEqualTo(null); + + assertThat(metrics.get(8).getMetricDescriptor()) + .isEqualTo( + MetricDescriptor.create( + "codahale_result_histogram", + "Collected from codahale (metric=result, " + "type=com.codahale.metrics.Histogram)", + DEFAULT_UNIT, + Type.SUMMARY, + Collections.<LabelKey>emptyList())); + assertThat(metrics.get(8).getTimeSeriesList().size()).isEqualTo(1); + assertThat(metrics.get(8).getTimeSeriesList().get(0).getLabelValues().size()).isEqualTo(0); + assertThat(metrics.get(8).getTimeSeriesList().get(0).getPoints().size()).isEqualTo(1); + assertThat(metrics.get(8).getTimeSeriesList().get(0).getPoints().get(0).getValue()) + .isEqualTo( + Value.summaryValue( + Summary.create( + 1L, + 0.0, + Snapshot.create( + 1L, + 0.0, + Arrays.asList( + ValueAtPercentile.create(50.0, 200.0), + ValueAtPercentile.create(75.0, 200.0), + ValueAtPercentile.create(98.0, 200.0), + ValueAtPercentile.create(99.0, 200.0), + ValueAtPercentile.create(99.9, 200.0)))))); + assertThat(metrics.get(8).getTimeSeriesList().get(0).getStartTimestamp()) + .isInstanceOf(Timestamp.class); + + assertThat(metrics.get(9).getMetricDescriptor()) + .isEqualTo( + MetricDescriptor.create( + "codahale_requests_timer", + "Collected from codahale (metric=requests, " + "type=com.codahale.metrics.Timer)", + DEFAULT_UNIT, + Type.SUMMARY, + Collections.<LabelKey>emptyList())); + assertThat(metrics.get(9).getTimeSeriesList().size()).isEqualTo(1); + assertThat(metrics.get(9).getTimeSeriesList().get(0).getLabelValues().size()).isEqualTo(0); + assertThat(metrics.get(9).getTimeSeriesList().get(0).getPoints().size()).isEqualTo(1); + assertThat(metrics.get(9).getTimeSeriesList().get(0).getPoints().get(0).getValue()) + .isEqualTo( + Value.summaryValue( + Summary.create( + 1L, + 0.0, + Snapshot.create( + 1L, + 0.0, + Arrays.asList( + ValueAtPercentile.create(50.0, timer.getSnapshot().getMedian()), + ValueAtPercentile.create(75.0, timer.getSnapshot().get75thPercentile()), + ValueAtPercentile.create(98.0, timer.getSnapshot().get98thPercentile()), + ValueAtPercentile.create(99.0, timer.getSnapshot().get99thPercentile()), + ValueAtPercentile.create( + 99.9, timer.getSnapshot().get999thPercentile())))))); + + assertThat(metrics.get(9).getTimeSeriesList().get(0).getStartTimestamp()) + .isInstanceOf(Timestamp.class); + } + + @Test + public void empty_GetMetrics() { + assertThat(dropWizardMetrics.getMetrics()).isEmpty(); + } +} diff --git a/contrib/dropwizard/src/test/java/io/opencensus/contrib/dropwizard/DropWizardUtilsTest.java b/contrib/dropwizard/src/test/java/io/opencensus/contrib/dropwizard/DropWizardUtilsTest.java new file mode 100644 index 00000000..4dd27f29 --- /dev/null +++ b/contrib/dropwizard/src/test/java/io/opencensus/contrib/dropwizard/DropWizardUtilsTest.java @@ -0,0 +1,41 @@ +/* + * Copyright 2018, OpenCensus Authors + * + * Licensed 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 io.opencensus.contrib.dropwizard; + +import static com.google.common.truth.Truth.assertThat; + +import com.codahale.metrics.Counter; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link DropWizardUtils}. */ +@RunWith(JUnit4.class) +public class DropWizardUtilsTest { + + @Test + public void generateFullMetricName() { + assertThat(DropWizardUtils.generateFullMetricName("requests", "gauge")) + .isEqualTo("codahale_requests_gauge"); + } + + @Test + public void generateFullMetricDescription() { + assertThat(DropWizardUtils.generateFullMetricDescription("Counter", new Counter())) + .isEqualTo("Collected from codahale (metric=Counter, type=com.codahale.metrics.Counter)"); + } +} diff --git a/settings.gradle b/settings.gradle index bdf68bdc..7c224edf 100644 --- a/settings.gradle +++ b/settings.gradle @@ -16,6 +16,7 @@ include ":opencensus-exporter-stats-stackdriver" include ":opencensus-exporter-stats-prometheus" include ":opencensus-contrib-agent" include ":opencensus-contrib-appengine-standard-util" +include ":opencensus-contrib-dropwizard" include ":opencensus-contrib-exemplar-util" include ":opencensus-contrib-grpc-metrics" include ":opencensus-contrib-grpc-util" @@ -34,6 +35,7 @@ project(':opencensus-testing').projectDir = "$rootDir/testing" as File project(':opencensus-contrib-agent').projectDir = "$rootDir/contrib/agent" as File project(':opencensus-contrib-appengine-standard-util').projectDir = "$rootDir/contrib/appengine_standard_util" as File +project(':opencensus-contrib-dropwizard').projectDir = "$rootDir/contrib/dropwizard" as File project(':opencensus-contrib-exemplar-util').projectDir = "$rootDir/contrib/exemplar_util" as File project(':opencensus-contrib-grpc-metrics').projectDir = "$rootDir/contrib/grpc_metrics" as File project(':opencensus-contrib-grpc-util').projectDir = "$rootDir/contrib/grpc_util" as File |