aboutsummaryrefslogtreecommitdiff
path: root/api/src/main/java/io/opencensus/metrics/export
diff options
context:
space:
mode:
Diffstat (limited to 'api/src/main/java/io/opencensus/metrics/export')
-rw-r--r--api/src/main/java/io/opencensus/metrics/export/Distribution.java280
-rw-r--r--api/src/main/java/io/opencensus/metrics/export/Metric.java104
-rw-r--r--api/src/main/java/io/opencensus/metrics/export/MetricDescriptor.java173
-rw-r--r--api/src/main/java/io/opencensus/metrics/export/MetricProducer.java40
-rw-r--r--api/src/main/java/io/opencensus/metrics/export/MetricProducerManager.java1
-rw-r--r--api/src/main/java/io/opencensus/metrics/export/Point.java63
-rw-r--r--api/src/main/java/io/opencensus/metrics/export/Summary.java187
-rw-r--r--api/src/main/java/io/opencensus/metrics/export/TimeSeries.java96
-rw-r--r--api/src/main/java/io/opencensus/metrics/export/Value.java246
9 files changed, 1189 insertions, 1 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..dc9fa9e9
--- /dev/null
+++ b/api/src/main/java/io/opencensus/metrics/export/Distribution.java
@@ -0,0 +1,280 @@
+/*
+ * 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.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 bucketBoundaries bucket boundaries of a histogram.
+ * @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,
+ List<Double> bucketBoundaries,
+ 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.");
+ }
+ return new AutoValue_Distribution(
+ count,
+ sum,
+ sumOfSquaredDeviations,
+ copyBucketBounds(bucketBoundaries),
+ copyBucketCount(buckets));
+ }
+
+ private static List<Double> copyBucketBounds(List<Double> bucketBoundaries) {
+ Utils.checkNotNull(bucketBoundaries, "bucketBoundaries list should not be null.");
+ List<Double> bucketBoundariesCopy = new ArrayList<Double>(bucketBoundaries); // Deep copy.
+ // Check if sorted.
+ if (bucketBoundariesCopy.size() > 1) {
+ double lower = bucketBoundariesCopy.get(0);
+ for (int i = 1; i < bucketBoundariesCopy.size(); i++) {
+ double next = bucketBoundariesCopy.get(i);
+ Utils.checkArgument(lower < next, "bucket boundaries not sorted.");
+ lower = next;
+ }
+ }
+ return Collections.unmodifiableList(bucketBoundariesCopy);
+ }
+
+ private static List<Bucket> copyBucketCount(List<Bucket> buckets) {
+ Utils.checkNotNull(buckets, "bucket list should not be null.");
+ List<Bucket> bucketsCopy = new ArrayList<Bucket>(buckets);
+ for (Bucket bucket : bucketsCopy) {
+ Utils.checkNotNull(bucket, "bucket should not be null.");
+ }
+ return Collections.unmodifiableList(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 the bucket boundaries of this distribution.
+ *
+ * <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 (-infinity, bucket_bounds[i]) for i == 0}
+ * <li>{@code [bucket_bounds[i-1], bucket_bounds[i]) for 0 < i < N-2}
+ * <li>{@code [bucket_bounds[i-1], +infinity) for i == N-1}
+ * </ul>
+ *
+ * <p>i.e. an underflow bucket (number 0), zero or more finite buckets (1 through N - 2, and an
+ * overflow bucket (N - 1), with inclusive lower bounds and exclusive upper bounds.
+ *
+ * <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.
+ *
+ * @return the bucket boundaries of this distribution.
+ * @since 0.17
+ */
+ public abstract List<Double> getBucketBoundaries();
+
+ /**
+ * Returns the aggregated histogram {@link Bucket}s.
+ *
+ * @return the aggregated histogram buckets.
+ * @since 0.17
+ */
+ public abstract List<Bucket> getBuckets();
+
+ /**
+ * 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);
+ }
+ }
+}
diff --git a/api/src/main/java/io/opencensus/metrics/export/Metric.java b/api/src/main/java/io/opencensus/metrics/export/Metric.java
new file mode 100644
index 00000000..07fe356a
--- /dev/null
+++ b/api/src/main/java/io/opencensus/metrics/export/Metric.java
@@ -0,0 +1,104 @@
+/*
+ * 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.internal.Utils;
+import io.opencensus.metrics.export.Value.ValueDistribution;
+import io.opencensus.metrics.export.Value.ValueDouble;
+import io.opencensus.metrics.export.Value.ValueLong;
+import io.opencensus.metrics.export.Value.ValueSummary;
+import java.util.List;
+import javax.annotation.concurrent.Immutable;
+
+/**
+ * A {@link Metric} with one or more {@link TimeSeries}.
+ *
+ * @since 0.17
+ */
+@ExperimentalApi
+@Immutable
+@AutoValue
+public abstract class Metric {
+
+ Metric() {}
+
+ /**
+ * Creates a {@link Metric}.
+ *
+ * @param metricDescriptor the {@link MetricDescriptor}.
+ * @param timeSeriesList the {@link TimeSeries} list for this metric.
+ * @return a {@code Metric}.
+ * @since 0.17
+ */
+ public static Metric create(MetricDescriptor metricDescriptor, List<TimeSeries> timeSeriesList) {
+ checkTypeMatch(metricDescriptor.getType(), timeSeriesList);
+ return new AutoValue_Metric(metricDescriptor, timeSeriesList);
+ }
+
+ /**
+ * Returns the {@link MetricDescriptor} of this metric.
+ *
+ * @return the {@code MetricDescriptor} of this metric.
+ * @since 0.17
+ */
+ public abstract MetricDescriptor getMetricDescriptor();
+
+ /**
+ * Returns the {@link TimeSeries} list for this metric.
+ *
+ * <p>The type of the {@link TimeSeries#getPoints()} must match {@link MetricDescriptor.Type}.
+ *
+ * @return the {@code TimeSeriesList} for this metric.
+ * @since 0.17
+ */
+ public abstract List<TimeSeries> getTimeSeriesList();
+
+ private static void checkTypeMatch(MetricDescriptor.Type type, List<TimeSeries> timeSeriesList) {
+ for (TimeSeries timeSeries : timeSeriesList) {
+ for (Point point : timeSeries.getPoints()) {
+ Value value = point.getValue();
+ String valueClassName = "";
+ if (value.getClass().getSuperclass() != null) { // work around nullness check
+ // AutoValue classes should always have a super class.
+ valueClassName = value.getClass().getSuperclass().getSimpleName();
+ }
+ switch (type) {
+ case GAUGE_INT64:
+ case CUMULATIVE_INT64:
+ Utils.checkArgument(
+ value instanceof ValueLong, "Type mismatch: %s, %s.", type, valueClassName);
+ break;
+ case CUMULATIVE_DOUBLE:
+ case GAUGE_DOUBLE:
+ Utils.checkArgument(
+ value instanceof ValueDouble, "Type mismatch: %s, %s.", type, valueClassName);
+ break;
+ case GAUGE_DISTRIBUTION:
+ case CUMULATIVE_DISTRIBUTION:
+ Utils.checkArgument(
+ value instanceof ValueDistribution, "Type mismatch: %s, %s.", type, valueClassName);
+ break;
+ case SUMMARY:
+ Utils.checkArgument(
+ value instanceof ValueSummary, "Type mismatch: %s, %s.", type, valueClassName);
+ }
+ }
+ }
+ }
+}
diff --git a/api/src/main/java/io/opencensus/metrics/export/MetricDescriptor.java b/api/src/main/java/io/opencensus/metrics/export/MetricDescriptor.java
new file mode 100644
index 00000000..a4629f8e
--- /dev/null
+++ b/api/src/main/java/io/opencensus/metrics/export/MetricDescriptor.java
@@ -0,0 +1,173 @@
+/*
+ * 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.internal.Utils;
+import io.opencensus.metrics.LabelKey;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import javax.annotation.concurrent.Immutable;
+
+/**
+ * {@link MetricDescriptor} defines a {@code Metric} type and its schema.
+ *
+ * @since 0.17
+ */
+@ExperimentalApi
+@Immutable
+@AutoValue
+public abstract class MetricDescriptor {
+
+ MetricDescriptor() {}
+
+ /**
+ * Creates a {@link MetricDescriptor}.
+ *
+ * @param name name of {@code MetricDescriptor}.
+ * @param description description of {@code MetricDescriptor}.
+ * @param unit the metric unit.
+ * @param type type of {@code MetricDescriptor}.
+ * @param labelKeys the label keys associated with the {@code MetricDescriptor}.
+ * @return a {@code MetricDescriptor}.
+ * @since 0.17
+ */
+ public static MetricDescriptor create(
+ String name, String description, String unit, Type type, List<LabelKey> labelKeys) {
+ Utils.checkNotNull(labelKeys, "labelKeys");
+ Utils.checkListElementNotNull(labelKeys, "labelKey");
+ return new AutoValue_MetricDescriptor(
+ name,
+ description,
+ unit,
+ type,
+ Collections.unmodifiableList(new ArrayList<LabelKey>(labelKeys)));
+ }
+
+ /**
+ * Returns the metric descriptor name.
+ *
+ * @return the metric descriptor name.
+ * @since 0.17
+ */
+ public abstract String getName();
+
+ /**
+ * Returns the description of this metric descriptor.
+ *
+ * @return the description of this metric descriptor.
+ * @since 0.17
+ */
+ public abstract String getDescription();
+
+ /**
+ * Returns the unit of this metric descriptor.
+ *
+ * @return the unit of this metric descriptor.
+ * @since 0.17
+ */
+ public abstract String getUnit();
+
+ /**
+ * Returns the type of this metric descriptor.
+ *
+ * @return the type of this metric descriptor.
+ * @since 0.17
+ */
+ public abstract Type getType();
+
+ /**
+ * Returns the label keys associated with this metric descriptor.
+ *
+ * @return the label keys associated with this metric descriptor.
+ * @since 0.17
+ */
+ public abstract List<LabelKey> getLabelKeys();
+
+ /**
+ * The kind of metric. It describes how the data is reported.
+ *
+ * <p>A gauge is an instantaneous measurement of a value.
+ *
+ * <p>A cumulative measurement is a value accumulated over a time interval. In a time series,
+ * cumulative measurements should have the same start time and increasing end times, until an
+ * event resets the cumulative value to zero and sets a new start time for the following points.
+ *
+ * @since 0.17
+ */
+ public enum Type {
+
+ /**
+ * An instantaneous measurement of an int64 value.
+ *
+ * @since 0.17
+ */
+ GAUGE_INT64,
+
+ /**
+ * An instantaneous measurement of a double value.
+ *
+ * @since 0.17
+ */
+ GAUGE_DOUBLE,
+
+ /**
+ * An instantaneous measurement of a distribution value. The count and sum can go both up and
+ * down. Used in scenarios like a snapshot of time the current items in a queue have spent
+ * there.
+ *
+ * @since 0.17
+ */
+ GAUGE_DISTRIBUTION,
+
+ /**
+ * An cumulative measurement of an int64 value.
+ *
+ * @since 0.17
+ */
+ CUMULATIVE_INT64,
+
+ /**
+ * An cumulative measurement of a double value.
+ *
+ * @since 0.17
+ */
+ CUMULATIVE_DOUBLE,
+
+ /**
+ * An cumulative measurement of a distribution value. The count and sum can only go up, if
+ * resets then the start_time should also be reset.
+ *
+ * @since 0.17
+ */
+ CUMULATIVE_DISTRIBUTION,
+
+ /**
+ * Some frameworks implemented DISTRIBUTION as a summary of observations (usually things like
+ * request durations and response sizes). While it also provides a total count of observations
+ * and a sum of all observed values, it calculates configurable quantiles over a sliding time
+ * window.
+ *
+ * <p>This is not recommended, since it cannot be aggregated.
+ *
+ * @since 0.17
+ */
+ SUMMARY,
+ }
+}
diff --git a/api/src/main/java/io/opencensus/metrics/export/MetricProducer.java b/api/src/main/java/io/opencensus/metrics/export/MetricProducer.java
new file mode 100644
index 00000000..739a0a9f
--- /dev/null
+++ b/api/src/main/java/io/opencensus/metrics/export/MetricProducer.java
@@ -0,0 +1,40 @@
+/*
+ * 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 io.opencensus.common.ExperimentalApi;
+import java.util.Collection;
+
+/**
+ * A {@link Metric} producer that can be registered for exporting using {@link
+ * MetricProducerManager}.
+ *
+ * <p>All implementation MUST be thread-safe.
+ *
+ * @since 0.17
+ */
+@ExperimentalApi
+public abstract class MetricProducer {
+
+ /**
+ * Returns a collection of produced {@link Metric}s to be exported.
+ *
+ * @return a collection of produced {@link Metric}s to be exported.
+ * @since 0.17
+ */
+ public abstract Collection<Metric> getMetrics();
+}
diff --git a/api/src/main/java/io/opencensus/metrics/export/MetricProducerManager.java b/api/src/main/java/io/opencensus/metrics/export/MetricProducerManager.java
index fc864200..304d9294 100644
--- a/api/src/main/java/io/opencensus/metrics/export/MetricProducerManager.java
+++ b/api/src/main/java/io/opencensus/metrics/export/MetricProducerManager.java
@@ -18,7 +18,6 @@ package io.opencensus.metrics.export;
import io.opencensus.common.ExperimentalApi;
import io.opencensus.internal.Utils;
-import io.opencensus.metrics.MetricProducer;
import java.util.Collections;
import java.util.Set;
import javax.annotation.concurrent.ThreadSafe;
diff --git a/api/src/main/java/io/opencensus/metrics/export/Point.java b/api/src/main/java/io/opencensus/metrics/export/Point.java
new file mode 100644
index 00000000..1f382f9b
--- /dev/null
+++ b/api/src/main/java/io/opencensus/metrics/export/Point.java
@@ -0,0 +1,63 @@
+/*
+ * 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.Timestamp;
+import javax.annotation.concurrent.Immutable;
+
+/**
+ * A timestamped measurement of a {@code TimeSeries}.
+ *
+ * @since 0.17
+ */
+@ExperimentalApi
+@AutoValue
+@Immutable
+public abstract class Point {
+
+ Point() {}
+
+ /**
+ * Creates a {@link Point}.
+ *
+ * @param value the {@link Value} of this {@link Point}.
+ * @param timestamp the {@link Timestamp} when this {@link Point} was recorded.
+ * @return a {@code Point}.
+ * @since 0.17
+ */
+ public static Point create(Value value, Timestamp timestamp) {
+ return new AutoValue_Point(value, timestamp);
+ }
+
+ /**
+ * Returns the {@link Value}.
+ *
+ * @return the {@code Value}.
+ * @since 0.17
+ */
+ public abstract Value getValue();
+
+ /**
+ * Returns the {@link Timestamp} when this {@link Point} was recorded.
+ *
+ * @return the {@code Timestamp}.
+ * @since 0.17
+ */
+ public abstract Timestamp getTimestamp();
+}
diff --git a/api/src/main/java/io/opencensus/metrics/export/Summary.java b/api/src/main/java/io/opencensus/metrics/export/Summary.java
new file mode 100644
index 00000000..c82ca961
--- /dev/null
+++ b/api/src/main/java/io/opencensus/metrics/export/Summary.java
@@ -0,0 +1,187 @@
+/*
+ * 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.internal.Utils;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.Immutable;
+
+/**
+ * Implementation of the {@link Distribution} as a summary of observations.
+ *
+ * <p>This is not recommended, since it cannot be aggregated.
+ *
+ * @since 0.17
+ */
+@ExperimentalApi
+@AutoValue
+@Immutable
+public abstract class Summary {
+ Summary() {}
+
+ /**
+ * Creates a {@link Summary}.
+ *
+ * @param count the count of the population values.
+ * @param sum the sum of the population values.
+ * @param snapshot bucket boundaries of a histogram.
+ * @return a {@code Summary} with the given values.
+ * @since 0.17
+ */
+ public static Summary create(@Nullable Long count, @Nullable Double sum, Snapshot snapshot) {
+ checkCountAndSum(count, sum);
+ Utils.checkNotNull(snapshot, "snapshot");
+ return new AutoValue_Summary(count, sum, snapshot);
+ }
+
+ /**
+ * Returns the aggregated count. If not available returns {@code null}.
+ *
+ * @return the aggregated count.
+ * @since 0.17
+ */
+ @Nullable
+ public abstract Long getCount();
+
+ /**
+ * Returns the aggregated sum. If not available returns {@code null}.
+ *
+ * @return the aggregated sum.
+ * @since 0.17
+ */
+ @Nullable
+ public abstract Double getSum();
+
+ /**
+ * Returns the {@link Snapshot}.
+ *
+ * @return the {@code Snapshot}.
+ * @since 0.17
+ */
+ public abstract Snapshot getSnapshot();
+
+ /**
+ * Represents the summary observation of the recorded events over a sliding time window.
+ *
+ * @since 0.17
+ */
+ @Immutable
+ @AutoValue
+ public abstract static class Snapshot {
+ /**
+ * Returns the number of values in this {@code Snapshot}. If not available returns {@code null}.
+ *
+ * @return the number of values in this {@code Snapshot}.
+ * @since 0.17
+ */
+ @Nullable
+ public abstract Long getCount();
+
+ /**
+ * Returns the sum of values in this {@code Snapshot}. If not available returns {@code null}.
+ *
+ * @return the sum of values in this {@code Snapshot}.
+ * @since 0.17
+ */
+ @Nullable
+ public abstract Double getSum();
+
+ /**
+ * Returns the list of {@code ValueAtPercentile}s in this {@code Snapshot}.
+ *
+ * @return the list of {@code ValueAtPercentile}s in this {@code Snapshot}.
+ * @since 0.17
+ */
+ public abstract List<ValueAtPercentile> getValueAtPercentiles();
+
+ /**
+ * Creates a {@link Snapshot}.
+ *
+ * @param count the number of values in this {@code Snapshot}.
+ * @param sum the number of values in this {@code Snapshot}.
+ * @param valueAtPercentiles the list of {@code ValueAtPercentile}.
+ * @return a {@code Snapshot} with the given values.
+ * @since 0.17
+ */
+ public static Snapshot create(
+ @Nullable Long count, @Nullable Double sum, List<ValueAtPercentile> valueAtPercentiles) {
+ checkCountAndSum(count, sum);
+ Utils.checkNotNull(valueAtPercentiles, "valueAtPercentiles");
+ Utils.checkListElementNotNull(valueAtPercentiles, "value in valueAtPercentiles");
+ return new AutoValue_Summary_Snapshot(
+ count,
+ sum,
+ Collections.unmodifiableList(new ArrayList<ValueAtPercentile>(valueAtPercentiles)));
+ }
+
+ /**
+ * Represents the value at a given percentile of a distribution.
+ *
+ * @since 0.17
+ */
+ @Immutable
+ @AutoValue
+ public abstract static class ValueAtPercentile {
+ /**
+ * Returns the percentile in this {@code ValueAtPercentile}.
+ *
+ * <p>Must be in the interval (0.0, 100.0].
+ *
+ * @return the percentile in this {@code ValueAtPercentile}.
+ * @since 0.17
+ */
+ public abstract double getPercentile();
+
+ /**
+ * Returns the value in this {@code ValueAtPercentile}.
+ *
+ * @return the value in this {@code ValueAtPercentile}.
+ * @since 0.17
+ */
+ public abstract double getValue();
+
+ /**
+ * Creates a {@link ValueAtPercentile}.
+ *
+ * @param percentile the percentile in this {@code ValueAtPercentile}.
+ * @param value the value in this {@code ValueAtPercentile}.
+ * @return a {@code ValueAtPercentile} with the given values.
+ * @since 0.17
+ */
+ public static ValueAtPercentile create(double percentile, double value) {
+ Utils.checkArgument(
+ 0 < percentile && percentile <= 100.0,
+ "percentile must be in the interval (0.0, 100.0]");
+ Utils.checkArgument(value >= 0, "value must be non-negative");
+ return new AutoValue_Summary_Snapshot_ValueAtPercentile(percentile, value);
+ }
+ }
+ }
+
+ private static void checkCountAndSum(@Nullable Long count, @Nullable Double sum) {
+ Utils.checkArgument(count == null || count >= 0, "count must be non-negative.");
+ Utils.checkArgument(sum == null || sum >= 0, "sum must be non-negative.");
+ if (count != null && count == 0) {
+ Utils.checkArgument(sum == null || sum == 0, "sum must be 0 if count is 0.");
+ }
+ }
+}
diff --git a/api/src/main/java/io/opencensus/metrics/export/TimeSeries.java b/api/src/main/java/io/opencensus/metrics/export/TimeSeries.java
new file mode 100644
index 00000000..959f55ba
--- /dev/null
+++ b/api/src/main/java/io/opencensus/metrics/export/TimeSeries.java
@@ -0,0 +1,96 @@
+/*
+ * 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.Timestamp;
+import io.opencensus.internal.Utils;
+import io.opencensus.metrics.LabelKey;
+import io.opencensus.metrics.LabelValue;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.Immutable;
+
+/**
+ * A collection of data points that describes the time-varying values of a {@code Metric}.
+ *
+ * @since 0.17
+ */
+@ExperimentalApi
+@Immutable
+@AutoValue
+public abstract class TimeSeries {
+
+ TimeSeries() {}
+
+ /**
+ * Creates a {@link TimeSeries}.
+ *
+ * @param labelValues the {@code LabelValue}s that uniquely identify this {@code TimeSeries}.
+ * @param points the data {@code Point}s of this {@code TimeSeries}.
+ * @param startTimestamp the start {@code Timestamp} of this {@code TimeSeries}. Must be non-null
+ * for cumulative {@code Point}s.
+ * @return a {@code TimeSeries}.
+ * @since 0.17
+ */
+ public static TimeSeries create(
+ List<LabelValue> labelValues, List<Point> points, @Nullable Timestamp startTimestamp) {
+ // Fail fast on null lists to prevent NullPointerException when copying the lists.
+ Utils.checkNotNull(labelValues, "labelValues");
+ Utils.checkNotNull(points, "points");
+ Utils.checkListElementNotNull(labelValues, "labelValue");
+ Utils.checkListElementNotNull(points, "point");
+ return new AutoValue_TimeSeries(
+ Collections.unmodifiableList(new ArrayList<LabelValue>(labelValues)),
+ Collections.unmodifiableList(new ArrayList<Point>(points)),
+ startTimestamp);
+ }
+
+ /**
+ * Returns the set of {@link LabelValue}s that uniquely identify this {@link TimeSeries}.
+ *
+ * <p>Apply to all {@link Point}s.
+ *
+ * <p>The order of {@link LabelValue}s must match that of {@link LabelKey}s in the {@code
+ * MetricDescriptor}.
+ *
+ * @return the {@code LabelValue}s.
+ * @since 0.17
+ */
+ public abstract List<LabelValue> getLabelValues();
+
+ /**
+ * Returns the data {@link Point}s of this {@link TimeSeries}.
+ *
+ * @return the data {@code Point}s.
+ * @since 0.17
+ */
+ public abstract List<Point> getPoints();
+
+ /**
+ * Returns the start {@link Timestamp} of this {@link TimeSeries} if the {@link Point}s are
+ * cumulative, or {@code null} if the {@link Point}s are gauge.
+ *
+ * @return the start {@code Timestamp} or {@code null}.
+ * @since 0.17
+ */
+ @Nullable
+ public abstract Timestamp getStartTimestamp();
+}
diff --git a/api/src/main/java/io/opencensus/metrics/export/Value.java b/api/src/main/java/io/opencensus/metrics/export/Value.java
new file mode 100644
index 00000000..00a939c0
--- /dev/null
+++ b/api/src/main/java/io/opencensus/metrics/export/Value.java
@@ -0,0 +1,246 @@
+/*
+ * 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 javax.annotation.concurrent.Immutable;
+
+/**
+ * The actual point value for a {@link Point}.
+ *
+ * <p>Currently there are three types of {@link Value}:
+ *
+ * <ul>
+ * <li>{@code double}
+ * <li>{@code long}
+ * <li>{@link Distribution}
+ * </ul>
+ *
+ * <p>Each {@link Point} contains exactly one of the three {@link Value} types.
+ *
+ * @since 0.17
+ */
+@ExperimentalApi
+@Immutable
+public abstract class Value {
+
+ Value() {}
+
+ /**
+ * Returns a double {@link Value}.
+ *
+ * @param value value in double.
+ * @return a double {@code Value}.
+ * @since 0.17
+ */
+ public static Value doubleValue(double value) {
+ return ValueDouble.create(value);
+ }
+
+ /**
+ * Returns a long {@link Value}.
+ *
+ * @param value value in long.
+ * @return a long {@code Value}.
+ * @since 0.17
+ */
+ public static Value longValue(long value) {
+ return ValueLong.create(value);
+ }
+
+ /**
+ * Returns a {@link Distribution} {@link Value}.
+ *
+ * @param value value in {@link Distribution}.
+ * @return a {@code Distribution} {@code Value}.
+ * @since 0.17
+ */
+ public static Value distributionValue(Distribution value) {
+ return ValueDistribution.create(value);
+ }
+
+ /**
+ * Returns a {@link Summary} {@link Value}.
+ *
+ * @param value value in {@link Summary}.
+ * @return a {@code Summary} {@code Value}.
+ * @since 0.17
+ */
+ public static Value summaryValue(Summary value) {
+ return ValueSummary.create(value);
+ }
+
+ /**
+ * Applies the given match function to the underlying data type.
+ *
+ * @since 0.17
+ */
+ public abstract <T> T match(
+ Function<? super Double, T> doubleFunction,
+ Function<? super Long, T> longFunction,
+ Function<? super Distribution, T> distributionFunction,
+ Function<? super Summary, T> summaryFunction,
+ Function<? super Value, T> defaultFunction);
+
+ /** A 64-bit double-precision floating-point {@link Value}. */
+ @AutoValue
+ @Immutable
+ abstract static class ValueDouble extends Value {
+
+ ValueDouble() {}
+
+ @Override
+ public final <T> T match(
+ Function<? super Double, T> doubleFunction,
+ Function<? super Long, T> longFunction,
+ Function<? super Distribution, T> distributionFunction,
+ Function<? super Summary, T> summaryFunction,
+ Function<? super Value, T> defaultFunction) {
+ return doubleFunction.apply(getValue());
+ }
+
+ /**
+ * Creates a {@link ValueDouble}.
+ *
+ * @param value the value in double.
+ * @return a {@code ValueDouble}.
+ */
+ static ValueDouble create(double value) {
+ return new AutoValue_Value_ValueDouble(value);
+ }
+
+ /**
+ * Returns the double value.
+ *
+ * @return the double value.
+ */
+ abstract double getValue();
+ }
+
+ /** A 64-bit integer {@link Value}. */
+ @AutoValue
+ @Immutable
+ abstract static class ValueLong extends Value {
+
+ ValueLong() {}
+
+ @Override
+ public final <T> T match(
+ Function<? super Double, T> doubleFunction,
+ Function<? super Long, T> longFunction,
+ Function<? super Distribution, T> distributionFunction,
+ Function<? super Summary, T> summaryFunction,
+ Function<? super Value, T> defaultFunction) {
+ return longFunction.apply(getValue());
+ }
+
+ /**
+ * Creates a {@link ValueLong}.
+ *
+ * @param value the value in long.
+ * @return a {@code ValueLong}.
+ */
+ static ValueLong create(long value) {
+ return new AutoValue_Value_ValueLong(value);
+ }
+
+ /**
+ * Returns the long value.
+ *
+ * @return the long value.
+ */
+ abstract long getValue();
+ }
+
+ /**
+ * {@link ValueDistribution} contains summary statistics for a population of values. It optionally
+ * contains a histogram representing the distribution of those values across a set of buckets.
+ */
+ @AutoValue
+ @Immutable
+ abstract static class ValueDistribution extends Value {
+
+ ValueDistribution() {}
+
+ @Override
+ public final <T> T match(
+ Function<? super Double, T> doubleFunction,
+ Function<? super Long, T> longFunction,
+ Function<? super Distribution, T> distributionFunction,
+ Function<? super Summary, T> summaryFunction,
+ Function<? super Value, T> defaultFunction) {
+ return distributionFunction.apply(getValue());
+ }
+
+ /**
+ * Creates a {@link ValueDistribution}.
+ *
+ * @param value the {@link Distribution} value.
+ * @return a {@code ValueDistribution}.
+ */
+ static ValueDistribution create(Distribution value) {
+ return new AutoValue_Value_ValueDistribution(value);
+ }
+
+ /**
+ * Returns the {@link Distribution} value.
+ *
+ * @return the {@code Distribution} value.
+ */
+ abstract Distribution getValue();
+ }
+
+ /**
+ * {@link ValueSummary} contains a snapshot representing values calculated over an arbitrary time
+ * window.
+ */
+ @AutoValue
+ @Immutable
+ abstract static class ValueSummary extends Value {
+
+ ValueSummary() {}
+
+ @Override
+ public final <T> T match(
+ Function<? super Double, T> doubleFunction,
+ Function<? super Long, T> longFunction,
+ Function<? super Distribution, T> distributionFunction,
+ Function<? super Summary, T> summaryFunction,
+ Function<? super Value, T> defaultFunction) {
+ return summaryFunction.apply(getValue());
+ }
+
+ /**
+ * Creates a {@link ValueSummary}.
+ *
+ * @param value the {@link Summary} value.
+ * @return a {@code ValueSummary}.
+ */
+ static ValueSummary create(Summary value) {
+ return new AutoValue_Value_ValueSummary(value);
+ }
+
+ /**
+ * Returns the {@link Summary} value.
+ *
+ * @return the {@code Summary} value.
+ */
+ abstract Summary getValue();
+ }
+}