Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,9 @@ static Metric toProtoMetric(MetricData metricData) {
.addAllDataPoints(toDoubleDataPoints(doubleGaugeData.getPoints()))
.build());
break;
case HISTOGRAM:
// no-op, will add in the following PRs
break;
}
return builder.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ static Collector.Type toMetricFamilyType(MetricData metricData) {
return Collector.Type.GAUGE;
case SUMMARY:
return Collector.Type.SUMMARY;
case HISTOGRAM:
return Collector.Type.HISTOGRAM;
}
return Collector.Type.UNKNOWN;
}
Expand Down Expand Up @@ -122,6 +124,9 @@ static List<Sample> toSamples(
addSummarySamples(
(DoubleSummaryPointData) pointData, name, labelNames, labelValues, samples);
break;
case HISTOGRAM:
// no-op, will add in the following PRs
break;
}
}
return samples;
Expand Down Expand Up @@ -189,6 +194,8 @@ private static Collection<? extends PointData> getPoints(MetricData metricData)
return metricData.getLongSumData().getPoints();
case SUMMARY:
return metricData.getDoubleSummaryData().getPoints();
case HISTOGRAM:
return metricData.getDoubleHistogramData().getPoints();
}
return Collections.emptyList();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.sdk.metrics.data;

import com.google.auto.value.AutoValue;
import java.util.Collection;
import javax.annotation.concurrent.Immutable;

@Immutable
@AutoValue
public abstract class DoubleHistogramData implements Data<DoubleHistogramPointData> {
DoubleHistogramData() {}

public static DoubleHistogramData create(
AggregationTemporality temporality, Collection<DoubleHistogramPointData> points) {
return new AutoValue_DoubleHistogramData(temporality, points);
}

/**
* Returns the {@code AggregationTemporality} of this metric,
*
* <p>AggregationTemporality describes if the aggregator reports delta changes since last report
* time, or cumulative changes since a fixed start time.
*
* @return the {@code AggregationTemporality} of this metric
*/
public abstract AggregationTemporality getAggregationTemporality();

@Override
public abstract Collection<DoubleHistogramPointData> getPoints();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.sdk.metrics.data;

import com.google.auto.value.AutoValue;
import io.opentelemetry.api.metrics.common.Labels;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.annotation.concurrent.Immutable;

/**
* DoubleHistogramPointData represents an approximate representation of the distribution of
* measurements.
*/
@Immutable
@AutoValue
public abstract class DoubleHistogramPointData implements PointData {
/**
* Functional interface for consuming bucket boundaries and counts as a sequence of pair values.
*/
public interface BucketConsumer {
void accept(double upperBound, long count);
}

/**
* Creates a DoubleHistogramPointData.
Comment thread
beanliu marked this conversation as resolved.
Outdated
*
* @return a DoubleHistogramPointData.
*/
public static DoubleHistogramPointData create(
long startEpochNanos,
long epochNanos,
Labels labels,
double sum,
long count,
List<Double> boundaries,
List<Long> counts) {
return new AutoValue_DoubleHistogramPointData(
startEpochNanos,
epochNanos,
labels,
sum,
count,
Collections.unmodifiableList(new ArrayList<>(boundaries)),
Collections.unmodifiableList(new ArrayList<>(counts)));
}

DoubleHistogramPointData() {}

/**
* The sum of all measurements recorded.
*
* @return the sum of recorded measurements.
*/
public abstract double getSum();

/**
* The number of measurements taken.
*
* @return the count of recorded measurements.
*/
public abstract long getCount();

/**
* The bucket boundaries. For a Histogram with N defined boundaries, e.g, [x, y, z]. There are N+1
* counts: [-inf, x), [x, y), [y, z), [z, +inf].
*
* @return the read-only bucket boundaries in increasing order. <b>do not mutate</b> the returned
* object.
*/
Comment thread
beanliu marked this conversation as resolved.
public abstract List<Double> getBoundaries();

/**
* The counts in each bucket.
*
* @return the read-only counts in each bucket. <b>do not mutate</b> the returned object.
*/
public abstract List<Long> getCounts();

/** Iterates over all the bucket boundaries and counts in this histogram. */
public void forEach(BucketConsumer action) {
Comment thread
beanliu marked this conversation as resolved.
Outdated
List<Double> boundaries = getBoundaries();
List<Long> counts = getCounts();
for (int i = 0; i < boundaries.size(); ++i) {
action.accept(boundaries.get(i), counts.get(i));
}
action.accept(Double.POSITIVE_INFINITY, counts.get(boundaries.size()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public abstract class MetricData {
/* isMonotonic= */ false, AggregationTemporality.CUMULATIVE, Collections.emptyList());
private static final DoubleSummaryData DEFAULT_DOUBLE_SUMMARY_DATA =
DoubleSummaryData.create(Collections.emptyList());
private static final DoubleHistogramData DEFAULT_DOUBLE_HISTOGRAM_DATA =
DoubleHistogramData.create(AggregationTemporality.CUMULATIVE, Collections.emptyList());

/**
* Returns a new MetricData wih a {@link MetricDataType#DOUBLE_GAUGE} type.
Expand Down Expand Up @@ -140,6 +142,28 @@ public static MetricData createDoubleSummary(
data);
}

/**
* Returns a new MetricData with a {@link MetricDataType#HISTOGRAM} type.
*
* @return a new MetricData wih a {@link MetricDataType#HISTOGRAM} type.
*/
public static MetricData createDoubleHistogram(
Resource resource,
InstrumentationLibraryInfo instrumentationLibraryInfo,
String name,
String description,
String unit,
DoubleHistogramData data) {
return new AutoValue_MetricData(
resource,
instrumentationLibraryInfo,
name,
description,
unit,
MetricDataType.HISTOGRAM,
data);
}

MetricData() {}

/**
Expand Down Expand Up @@ -265,4 +289,18 @@ public final DoubleSummaryData getDoubleSummaryData() {
}
return DEFAULT_DOUBLE_SUMMARY_DATA;
}

/**
* Returns the {@code DoubleHistogramData} if type is {@link MetricDataType#HISTOGRAM}, otherwise
* a default empty data.
*
* @return the {@code DoubleHistogramData} if type is {@link MetricDataType#HISTOGRAM}, otherwise
* a default empty data.
*/
public final DoubleHistogramData getDoubleHistogramData() {
if (getType() == MetricDataType.HISTOGRAM) {
return (DoubleHistogramData) getData();
}
return DEFAULT_DOUBLE_HISTOGRAM_DATA;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,10 @@ public enum MetricDataType {
* value recorded, the sum of all measurements and the total number of measurements recorded.
*/
SUMMARY,

/**
* A Histogram represents an approximate representation of the distribution of measurements
* recorded.
*/
HISTOGRAM,
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@

import static org.assertj.core.api.Assertions.assertThat;

import com.google.common.collect.ImmutableList;
import io.opentelemetry.api.metrics.common.Labels;
import io.opentelemetry.sdk.common.InstrumentationLibraryInfo;
import io.opentelemetry.sdk.resources.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -40,6 +43,15 @@ class MetricDataTest {
Arrays.asList(
ValueAtPercentile.create(0.0, DOUBLE_VALUE),
ValueAtPercentile.create(100, DOUBLE_VALUE)));
private static final DoubleHistogramPointData HISTOGRAM_POINT =
DoubleHistogramPointData.create(
START_EPOCH_NANOS,
EPOCH_NANOS,
Labels.of("key", "value"),
DOUBLE_VALUE,
LONG_VALUE,
ImmutableList.of(1.0),
ImmutableList.of(1L, 1L));

@Test
void metricData_Getters() {
Expand Down Expand Up @@ -146,6 +158,39 @@ void metricData_SummaryPoints() {
assertThat(metricData.getDoubleSummaryData().getPoints()).containsExactly(SUMMARY_POINT);
}

@Test
void metricData_HistogramPoints() {
assertThat(HISTOGRAM_POINT.getStartEpochNanos()).isEqualTo(START_EPOCH_NANOS);
assertThat(HISTOGRAM_POINT.getEpochNanos()).isEqualTo(EPOCH_NANOS);
assertThat(HISTOGRAM_POINT.getLabels().size()).isEqualTo(1);
assertThat(HISTOGRAM_POINT.getLabels().get("key")).isEqualTo("value");
assertThat(HISTOGRAM_POINT.getCount()).isEqualTo(LONG_VALUE);
assertThat(HISTOGRAM_POINT.getSum()).isEqualTo(DOUBLE_VALUE);
assertThat(HISTOGRAM_POINT.getBoundaries()).isEqualTo(ImmutableList.of(1.0));
assertThat(HISTOGRAM_POINT.getCounts()).isEqualTo(ImmutableList.of(1L, 1L));

List<Double> boundaries = new ArrayList<>();
List<Long> counts = new ArrayList<>();
HISTOGRAM_POINT.forEach(
(b, c) -> {
boundaries.add(b);
counts.add(c);
});
assertThat(boundaries).isEqualTo(Arrays.asList(1.0, Double.POSITIVE_INFINITY));
assertThat(counts).isEqualTo(ImmutableList.of(1L, 1L));

MetricData metricData =
MetricData.createDoubleHistogram(
Resource.empty(),
InstrumentationLibraryInfo.empty(),
"metric_name",
"metric_description",
"ms",
DoubleHistogramData.create(
AggregationTemporality.DELTA, Collections.singleton(HISTOGRAM_POINT)));
assertThat(metricData.getDoubleHistogramData().getPoints()).containsExactly(HISTOGRAM_POINT);
}

@Test
void metricData_GetDefault() {
MetricData metricData =
Expand All @@ -160,6 +205,7 @@ void metricData_GetDefault() {
assertThat(metricData.getLongGaugeData().getPoints()).isEmpty();
assertThat(metricData.getDoubleSumData().getPoints()).isEmpty();
assertThat(metricData.getLongGaugeData().getPoints()).isEmpty();
assertThat(metricData.getDoubleHistogramData().getPoints()).isEmpty();
assertThat(metricData.getDoubleSummaryData().getPoints()).containsExactly(SUMMARY_POINT);

metricData =
Expand All @@ -174,6 +220,7 @@ void metricData_GetDefault() {
assertThat(metricData.getLongGaugeData().getPoints()).isEmpty();
assertThat(metricData.getDoubleSumData().getPoints()).isEmpty();
assertThat(metricData.getLongGaugeData().getPoints()).isEmpty();
assertThat(metricData.getDoubleHistogramData().getPoints()).isEmpty();
assertThat(metricData.getDoubleSummaryData().getPoints()).isEmpty();
}
}