aboutsummaryrefslogtreecommitdiff
path: root/api/src/main/java/io/opencensus/metrics/export/Distribution.java
diff options
context:
space:
mode:
Diffstat (limited to 'api/src/main/java/io/opencensus/metrics/export/Distribution.java')
-rw-r--r--api/src/main/java/io/opencensus/metrics/export/Distribution.java345
1 files changed, 345 insertions, 0 deletions
diff --git a/api/src/main/java/io/opencensus/metrics/export/Distribution.java b/api/src/main/java/io/opencensus/metrics/export/Distribution.java
new file mode 100644
index 00000000..d55f101c
--- /dev/null
+++ b/api/src/main/java/io/opencensus/metrics/export/Distribution.java
@@ -0,0 +1,345 @@
+/*
+ * 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.metrics.export;
+
+import com.google.auto.value.AutoValue;
+import io.opencensus.common.ExperimentalApi;
+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.Nullable;
+import javax.annotation.concurrent.Immutable;
+
+/**
+ * {@link Distribution} contains summary statistics for a population of values. It optionally
+ * contains a histogram representing the distribution of those values across a set of buckets.
+ *
+ * @since 0.17
+ */
+@ExperimentalApi
+@AutoValue
+@Immutable
+public abstract class Distribution {
+
+ Distribution() {}
+
+ /**
+ * Creates a {@link Distribution}.
+ *
+ * @param count the count of the population values.
+ * @param sum the sum of the population values.
+ * @param sumOfSquaredDeviations the sum of squared deviations of the population values.
+ * @param bucketOptions the bucket options used to create a histogram for the distribution.
+ * @param buckets {@link Bucket}s of a histogram.
+ * @return a {@code Distribution}.
+ * @since 0.17
+ */
+ public static Distribution create(
+ long count,
+ double sum,
+ double sumOfSquaredDeviations,
+ BucketOptions bucketOptions,
+ List<Bucket> buckets) {
+ Utils.checkArgument(count >= 0, "count should be non-negative.");
+ Utils.checkArgument(
+ sumOfSquaredDeviations >= 0, "sum of squared deviations should be non-negative.");
+ if (count == 0) {
+ Utils.checkArgument(sum == 0, "sum should be 0 if count is 0.");
+ Utils.checkArgument(
+ sumOfSquaredDeviations == 0, "sum of squared deviations should be 0 if count is 0.");
+ }
+ Utils.checkNotNull(bucketOptions, "bucketOptions");
+ List<Bucket> bucketsCopy =
+ Collections.unmodifiableList(new ArrayList<Bucket>(Utils.checkNotNull(buckets, "buckets")));
+ Utils.checkListElementNotNull(bucketsCopy, "bucket");
+ return new AutoValue_Distribution(
+ count, sum, sumOfSquaredDeviations, bucketOptions, bucketsCopy);
+ }
+
+ /**
+ * Returns the aggregated count.
+ *
+ * @return the aggregated count.
+ * @since 0.17
+ */
+ public abstract long getCount();
+
+ /**
+ * Returns the aggregated sum.
+ *
+ * @return the aggregated sum.
+ * @since 0.17
+ */
+ public abstract double getSum();
+
+ /**
+ * Returns the aggregated sum of squared deviations.
+ *
+ * <p>The sum of squared deviations from the mean of the values in the population. For values x_i
+ * this is:
+ *
+ * <p>Sum[i=1..n]((x_i - mean)^2)
+ *
+ * <p>If count is zero then this field must be zero.
+ *
+ * @return the aggregated sum of squared deviations.
+ * @since 0.17
+ */
+ public abstract double getSumOfSquaredDeviations();
+
+ /**
+ * Returns bucket options used to create a histogram for the distribution.
+ *
+ * @return the {@code BucketOptions} associated with the {@code Distribution}, or {@code null} if
+ * there isn't one.
+ * @since 0.17
+ */
+ @Nullable
+ public abstract BucketOptions getBucketOptions();
+
+ /**
+ * Returns the aggregated histogram {@link Bucket}s.
+ *
+ * @return the aggregated histogram buckets.
+ * @since 0.17
+ */
+ public abstract List<Bucket> getBuckets();
+
+ /**
+ * The bucket options used to create a histogram for the distribution.
+ *
+ * @since 0.17
+ */
+ @Immutable
+ public abstract static class BucketOptions {
+
+ private BucketOptions() {}
+
+ /**
+ * Returns a {@link ExplicitOptions}.
+ *
+ * <p>The bucket boundaries for that histogram are described by bucket_bounds. This defines
+ * size(bucket_bounds) + 1 (= N) buckets. The boundaries for bucket index i are:
+ *
+ * <ul>
+ * <li>{@code [0, bucket_bounds[i]) for i == 0}
+ * <li>{@code [bucket_bounds[i-1], bucket_bounds[i]) for 0 < i < N-1}
+ * <li>{@code [bucket_bounds[i-1], +infinity) for i == N-1}
+ * </ul>
+ *
+ * <p>If bucket_bounds has no elements (zero size), then there is no histogram associated with
+ * the Distribution. If bucket_bounds has only one element, there are no finite buckets, and
+ * that single element is the common boundary of the overflow and underflow buckets. The values
+ * must be monotonically increasing.
+ *
+ * @param bucketBoundaries the bucket boundaries of a distribution (given explicitly). The
+ * values must be strictly increasing and should be positive values.
+ * @return a {@code ExplicitOptions} {@code BucketOptions}.
+ * @since 0.17
+ */
+ public static BucketOptions explicitOptions(List<Double> bucketBoundaries) {
+ return ExplicitOptions.create(bucketBoundaries);
+ }
+
+ /**
+ * Applies the given match function to the underlying BucketOptions.
+ *
+ * @param explicitFunction the function that should be applied if the BucketOptions has type
+ * {@code ExplicitOptions}.
+ * @param defaultFunction the function that should be applied if the BucketOptions has a type
+ * that was added after this {@code match} method was added to the API. See {@link
+ * io.opencensus.common.Functions} for some common functions for handling unknown types.
+ * @return the result of the function applied to the underlying BucketOptions.
+ * @since 0.17
+ */
+ public abstract <T> T match(
+ Function<? super ExplicitOptions, T> explicitFunction,
+ Function<? super BucketOptions, T> defaultFunction);
+
+ /** A Bucket with explicit bounds {@link BucketOptions}. */
+ @AutoValue
+ @Immutable
+ public abstract static class ExplicitOptions extends BucketOptions {
+
+ ExplicitOptions() {}
+
+ @Override
+ public final <T> T match(
+ Function<? super ExplicitOptions, T> explicitFunction,
+ Function<? super BucketOptions, T> defaultFunction) {
+ return explicitFunction.apply(this);
+ }
+
+ /**
+ * Creates a {@link ExplicitOptions}.
+ *
+ * @param bucketBoundaries the bucket boundaries of a distribution (given explicitly). The
+ * values must be strictly increasing and should be positive.
+ * @return a {@code ExplicitOptions}.
+ * @since 0.17
+ */
+ private static ExplicitOptions create(List<Double> bucketBoundaries) {
+ Utils.checkNotNull(bucketBoundaries, "bucketBoundaries");
+ List<Double> bucketBoundariesCopy =
+ Collections.unmodifiableList(new ArrayList<Double>(bucketBoundaries));
+ checkBucketBoundsAreSorted(bucketBoundariesCopy);
+ return new AutoValue_Distribution_BucketOptions_ExplicitOptions(bucketBoundariesCopy);
+ }
+
+ private static void checkBucketBoundsAreSorted(List<Double> bucketBoundaries) {
+ if (bucketBoundaries.size() >= 1) {
+ double previous = Utils.checkNotNull(bucketBoundaries.get(0), "bucketBoundary");
+ Utils.checkArgument(previous > 0, "bucket boundary should be > 0");
+ for (int i = 1; i < bucketBoundaries.size(); i++) {
+ double next = Utils.checkNotNull(bucketBoundaries.get(i), "bucketBoundary");
+ Utils.checkArgument(previous < next, "bucket boundaries not sorted.");
+ previous = next;
+ }
+ }
+ }
+
+ /**
+ * Returns the bucket boundaries of this distribution.
+ *
+ * @return the bucket boundaries of this distribution.
+ * @since 0.17
+ */
+ public abstract List<Double> getBucketBoundaries();
+ }
+ }
+
+ /**
+ * The histogram bucket of the population values.
+ *
+ * @since 0.17
+ */
+ @AutoValue
+ @Immutable
+ public abstract static class Bucket {
+
+ Bucket() {}
+
+ /**
+ * Creates a {@link Bucket}.
+ *
+ * @param count the number of values in each bucket of the histogram.
+ * @return a {@code Bucket}.
+ * @since 0.17
+ */
+ public static Bucket create(long count) {
+ Utils.checkArgument(count >= 0, "bucket count should be non-negative.");
+ return new AutoValue_Distribution_Bucket(count, null);
+ }
+
+ /**
+ * Creates a {@link Bucket} with an {@link Exemplar}.
+ *
+ * @param count the number of values in each bucket of the histogram.
+ * @param exemplar the {@code Exemplar} of this {@code Bucket}.
+ * @return a {@code Bucket}.
+ * @since 0.17
+ */
+ public static Bucket create(long count, Exemplar exemplar) {
+ Utils.checkArgument(count >= 0, "bucket count should be non-negative.");
+ Utils.checkNotNull(exemplar, "exemplar");
+ return new AutoValue_Distribution_Bucket(count, exemplar);
+ }
+
+ /**
+ * Returns the number of values in each bucket of the histogram.
+ *
+ * @return the number of values in each bucket of the histogram.
+ * @since 0.17
+ */
+ public abstract long getCount();
+
+ /**
+ * Returns the {@link Exemplar} associated with the {@link Bucket}, or {@code null} if there
+ * isn't one.
+ *
+ * @return the {@code Exemplar} associated with the {@code Bucket}, or {@code null} if there
+ * isn't one.
+ * @since 0.17
+ */
+ @Nullable
+ public abstract Exemplar getExemplar();
+ }
+
+ /**
+ * An example point that may be used to annotate aggregated distribution values, associated with a
+ * histogram bucket.
+ *
+ * @since 0.17
+ */
+ @Immutable
+ @AutoValue
+ public abstract static class Exemplar {
+
+ Exemplar() {}
+
+ /**
+ * Returns value of the {@link Exemplar} point.
+ *
+ * @return value of the {@code Exemplar} point.
+ * @since 0.17
+ */
+ 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.17
+ */
+ 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.17
+ */
+ 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.17
+ */
+ 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_Distribution_Exemplar(value, timestamp, attachmentsCopy);
+ }
+ }
+}