diff options
author | Yang Song <songy23@users.noreply.github.com> | 2018-06-29 11:48:27 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-29 11:48:27 -0700 |
commit | a7893d2a3fc4ef7fae138b67b22f3ffd51e5f529 (patch) | |
tree | 5c1cd53b0ae2acc49a50950e6d4ea48542bee1fc /api | |
parent | 273c9536f9ec33af05830ce9d7aaf37e35fd86db (diff) | |
download | opencensus-java-a7893d2a3fc4ef7fae138b67b22f3ffd51e5f529.tar.gz |
Stats: Add Exemplar class to DistributionData. (#1287)
Diffstat (limited to 'api')
-rw-r--r-- | api/src/main/java/io/opencensus/stats/AggregationData.java | 119 | ||||
-rw-r--r-- | api/src/test/java/io/opencensus/stats/AggregationDataTest.java | 63 |
2 files changed, 179 insertions, 3 deletions
diff --git a/api/src/main/java/io/opencensus/stats/AggregationData.java b/api/src/main/java/io/opencensus/stats/AggregationData.java index 95ac3282..eb7d40b3 100644 --- a/api/src/main/java/io/opencensus/stats/AggregationData.java +++ b/api/src/main/java/io/opencensus/stats/AggregationData.java @@ -18,10 +18,14 @@ package io.opencensus.stats; import com.google.auto.value.AutoValue; import io.opencensus.common.Function; +import io.opencensus.common.Timestamp; import io.opencensus.internal.Utils; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import javax.annotation.concurrent.Immutable; /** @@ -268,8 +272,9 @@ public abstract class AggregationData { * @param max max value. * @param sumOfSquaredDeviations sum of squared deviations. * @param bucketCounts histogram bucket counts. + * @param exemplars the exemplars associated with histogram buckets. * @return a {@code DistributionData}. - * @since 0.8 + * @since 0.16 */ public static DistributionData create( double mean, @@ -277,7 +282,8 @@ public abstract class AggregationData { double min, double max, double sumOfSquaredDeviations, - List<Long> bucketCounts) { + List<Long> bucketCounts, + List<Exemplar> exemplars) { if (min != Double.POSITIVE_INFINITY || max != Double.NEGATIVE_INFINITY) { Utils.checkArgument(min <= max, "max should be greater or equal to min."); } @@ -288,8 +294,48 @@ public abstract class AggregationData { Utils.checkNotNull(bucket, "bucket should not be null."); } + Utils.checkNotNull(exemplars, "exemplar list should not be null."); + for (Exemplar exemplar : exemplars) { + Utils.checkNotNull(exemplar, "exemplar should not be null."); + } + return new AutoValue_AggregationData_DistributionData( - mean, count, min, max, sumOfSquaredDeviations, bucketCountsCopy); + mean, + count, + min, + max, + sumOfSquaredDeviations, + bucketCountsCopy, + Collections.<Exemplar>unmodifiableList(new ArrayList<Exemplar>(exemplars))); + } + + /** + * Creates a {@code DistributionData}. + * + * @param mean mean value. + * @param count count value. + * @param min min value. + * @param max max value. + * @param sumOfSquaredDeviations sum of squared deviations. + * @param bucketCounts histogram bucket counts. + * @return a {@code DistributionData}. + * @since 0.8 + */ + public static DistributionData create( + double mean, + long count, + double min, + double max, + double sumOfSquaredDeviations, + List<Long> bucketCounts) { + return create( + mean, + count, + min, + max, + sumOfSquaredDeviations, + bucketCounts, + Collections.<Exemplar>emptyList()); } /** @@ -341,6 +387,14 @@ public abstract class AggregationData { */ public abstract List<Long> getBucketCounts(); + /** + * Returns the {@link Exemplar}s associated with histogram buckets. + * + * @return the {@code Exemplar}s associated with histogram buckets. + * @since 0.16 + */ + public abstract List<Exemplar> getExemplars(); + @Override public final <T> T match( Function<? super SumDataDouble, T> p0, @@ -352,6 +406,65 @@ public abstract class AggregationData { Function<? super AggregationData, T> defaultFunction) { return p3.apply(this); } + + /** + * An example point that may be used to annotate aggregated distribution values, associated with + * a histogram bucket. + * + * @since 0.16 + */ + @Immutable + @AutoValue + public abstract static class Exemplar { + + Exemplar() {} + + /** + * Returns value of the {@link Exemplar} point. + * + * @return value of the {@code Exemplar} point. + * @since 0.16 + */ + public abstract double getValue(); + + /** + * Returns the time that this {@link Exemplar}'s value was recorded. + * + * @return the time that this {@code Exemplar}'s value was recorded. + * @since 0.16 + */ + public abstract Timestamp getTimestamp(); + + /** + * Returns the contextual information about the example value, represented as a string map. + * + * @return the contextual information about the example value. + * @since 0.16 + */ + public abstract Map<String, String> getAttachments(); + + /** + * Creates an {@link Exemplar}. + * + * @param value value of the {@link Exemplar} point. + * @param timestamp the time that this {@code Exemplar}'s value was recorded. + * @param attachments the contextual information about the example value. + * @return an {@code Exemplar}. + * @since 0.16 + */ + public static Exemplar create( + double value, Timestamp timestamp, Map<String, String> attachments) { + Utils.checkNotNull(attachments, "attachments"); + Map<String, String> attachmentsCopy = + Collections.unmodifiableMap(new HashMap<String, String>(attachments)); + for (Entry<String, String> entry : attachmentsCopy.entrySet()) { + Utils.checkNotNull(entry.getKey(), "key of attachments"); + Utils.checkNotNull(entry.getValue(), "value of attachments"); + } + return new AutoValue_AggregationData_DistributionData_Exemplar( + value, timestamp, attachmentsCopy); + } + } } /** diff --git a/api/src/test/java/io/opencensus/stats/AggregationDataTest.java b/api/src/test/java/io/opencensus/stats/AggregationDataTest.java index 9f2aa589..60551600 100644 --- a/api/src/test/java/io/opencensus/stats/AggregationDataTest.java +++ b/api/src/test/java/io/opencensus/stats/AggregationDataTest.java @@ -21,8 +21,10 @@ import static com.google.common.truth.Truth.assertThat; import com.google.common.testing.EqualsTester; import io.opencensus.common.Function; import io.opencensus.common.Functions; +import io.opencensus.common.Timestamp; import io.opencensus.stats.AggregationData.CountData; import io.opencensus.stats.AggregationData.DistributionData; +import io.opencensus.stats.AggregationData.DistributionData.Exemplar; import io.opencensus.stats.AggregationData.LastValueDataDouble; import io.opencensus.stats.AggregationData.LastValueDataLong; import io.opencensus.stats.AggregationData.MeanData; @@ -30,7 +32,9 @@ import io.opencensus.stats.AggregationData.SumDataDouble; import io.opencensus.stats.AggregationData.SumDataLong; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.Map; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -42,6 +46,9 @@ import org.junit.runners.JUnit4; public class AggregationDataTest { private static final double TOLERANCE = 1e-6; + private static final Timestamp TIMESTAMP_1 = Timestamp.create(1, 0); + private static final Timestamp TIMESTAMP_2 = Timestamp.create(2, 0); + private static final Map<String, String> ATTACHMENTS = Collections.singletonMap("key", "value"); @Rule public ExpectedException thrown = ExpectedException.none(); @@ -58,6 +65,47 @@ public class AggregationDataTest { } @Test + public void testCreateDistributionDataWithExemplar() { + Exemplar exemplar1 = Exemplar.create(4, TIMESTAMP_2, ATTACHMENTS); + Exemplar exemplar2 = Exemplar.create(1, TIMESTAMP_1, ATTACHMENTS); + DistributionData distributionData = + DistributionData.create( + 7.7, 10, 1.1, 9.9, 32.2, Arrays.asList(4L, 1L), Arrays.asList(exemplar1, exemplar2)); + assertThat(distributionData.getExemplars()).containsExactly(exemplar1, exemplar2).inOrder(); + } + + @Test + public void testExemplar() { + Exemplar exemplar = Exemplar.create(15.0, TIMESTAMP_1, ATTACHMENTS); + assertThat(exemplar.getValue()).isEqualTo(15.0); + assertThat(exemplar.getTimestamp()).isEqualTo(TIMESTAMP_1); + assertThat(exemplar.getAttachments()).isEqualTo(ATTACHMENTS); + } + + @Test + public void testExemplar_PreventNullAttachments() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("attachments"); + Exemplar.create(15, TIMESTAMP_1, null); + } + + @Test + public void testExemplar_PreventNullAttachmentKey() { + Map<String, String> attachments = Collections.singletonMap(null, "value"); + thrown.expect(NullPointerException.class); + thrown.expectMessage("key of attachment"); + Exemplar.create(15, TIMESTAMP_1, attachments); + } + + @Test + public void testExemplar_PreventNullAttachmentValue() { + Map<String, String> attachments = Collections.singletonMap("key", null); + thrown.expect(NullPointerException.class); + thrown.expectMessage("value of attachment"); + Exemplar.create(15, TIMESTAMP_1, attachments); + } + + @Test public void preventNullBucketCountList() { thrown.expect(NullPointerException.class); thrown.expectMessage("bucket counts should not be null."); @@ -72,6 +120,21 @@ public class AggregationDataTest { } @Test + public void preventNullExemplarList() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("exemplar list should not be null."); + DistributionData.create(1, 1, 1, 1, 0, Arrays.asList(0L, 1L, 1L), null); + } + + @Test + public void preventNullExemplar() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("exemplar should not be null."); + DistributionData.create( + 1, 1, 1, 1, 0, Arrays.asList(0L, 1L, 1L), Collections.<Exemplar>singletonList(null)); + } + + @Test public void preventMinIsGreaterThanMax() { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("max should be greater or equal to min."); |