Skip to content

Commit

Permalink
Support bucket configuration for Histograms
Browse files Browse the repository at this point in the history
  • Loading branch information
lenin-jaganathan committed Aug 8, 2024
1 parent 718f3c2 commit 6be37b0
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ protected TimeUnit getBaseTimeUnit() {
protected DistributionStatisticConfig defaultHistogramConfig() {
return DistributionStatisticConfig.builder()
.expiry(this.config.step())
.maxBucketCount(this.config.maxBucketCount())
.build()
.merge(DistributionStatisticConfig.DEFAULT);
}
Expand Down Expand Up @@ -405,11 +406,14 @@ static Histogram getHistogram(final Clock clock, final DistributionStatisticConf
minimumExpectedValue = 0.0;
}

final int maxBucketCount = distributionStatisticConfig.getMaxBucketCount() != null ?
distributionStatisticConfig.getMaxBucketCount() : otlpConfig.maxBucketCount();
return otlpConfig.aggregationTemporality() == AggregationTemporality.DELTA
? new DeltaBase2ExponentialHistogram(otlpConfig.maxScale(), otlpConfig.maxBucketCount(),
minimumExpectedValue, baseTimeUnit, clock, otlpConfig.step().toMillis())
: new CumulativeBase2ExponentialHistogram(otlpConfig.maxScale(), otlpConfig.maxBucketCount(),
minimumExpectedValue, baseTimeUnit);
? new DeltaBase2ExponentialHistogram(otlpConfig.maxScale(),
maxBucketCount, minimumExpectedValue, baseTimeUnit,
clock, otlpConfig.step().toMillis())
: new CumulativeBase2ExponentialHistogram(otlpConfig.maxScale(),
maxBucketCount, minimumExpectedValue, baseTimeUnit);
}

Histogram explicitBucketHistogram = getExplicitBucketHistogram(clock, distributionStatisticConfig,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,13 @@ public B maximumExpectedValue(@Nullable Duration max) {
return (B) this;
}

public B maxBucketCount(@Nullable Integer maxBucketCount) {
if (maxBucketCount != null) {
this.distributionConfigBuilder.maxBucketCount(maxBucketCount);
}
return (B) this;
}

/**
* Statistics emanating from a timer like max, percentiles, and histogram counts decay
* over time to give greater weight to recent samples (exception: histogram counts are
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,13 @@ public Builder maximumExpectedValue(@Nullable Double max) {
return this;
}

public Builder maxBucketCount(@Nullable Integer maxBucketCount) {
if (maxBucketCount != null) {
this.distributionConfigBuilder.maxBucketCount(maxBucketCount);
}
return this;
}

/**
* Statistics emanating from a distribution summary like max, percentiles, and
* histogram counts decay over time to give greater weight to recent samples
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,13 @@ public Builder maximumExpectedValue(@Nullable Duration max) {
return this;
}

public Builder maxBucketCount(@Nullable Integer maxBucketCount) {
if (maxBucketCount != null) {
this.distributionConfigBuilder.maxBucketCount(maxBucketCount);
}
return this;
}

/**
* Statistics emanating from a timer like max, percentiles, and histogram counts
* decay over time to give greater weight to recent samples (exception: histogram
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.time.Duration;
import java.util.NavigableSet;
import java.util.TreeSet;
import java.util.stream.Collectors;
import java.util.stream.LongStream;

/**
Expand All @@ -41,6 +42,7 @@ public class DistributionStatisticConfig implements Mergeable<DistributionStatis
.percentilePrecision(1)
.minimumExpectedValue(1.0)
.maximumExpectedValue(Double.POSITIVE_INFINITY)
.maxBucketCount(Integer.MAX_VALUE)
.expiry(Duration.ofMinutes(2))
.bufferLength(3)
.build();
Expand Down Expand Up @@ -71,6 +73,9 @@ public class DistributionStatisticConfig implements Mergeable<DistributionStatis
@Nullable
private Integer bufferLength;

@Nullable
private Integer maxBucketCount;

public static Builder builder() {
return new Builder();
}
Expand All @@ -96,6 +101,7 @@ public DistributionStatisticConfig merge(DistributionStatisticConfig parent) {
this.minimumExpectedValue == null ? parent.minimumExpectedValue : this.minimumExpectedValue)
.maximumExpectedValue(
this.maximumExpectedValue == null ? parent.maximumExpectedValue : this.maximumExpectedValue)
.maxBucketCount(this.maxBucketCount == null ? parent.maxBucketCount : this.maxBucketCount)
.expiry(this.expiry == null ? parent.expiry : this.expiry)
.bufferLength(this.bufferLength == null ? parent.bufferLength : this.bufferLength)
.build();
Expand All @@ -121,6 +127,10 @@ public NavigableSet<Double> getHistogramBuckets(boolean supportsAggregablePercen
}
}

if (maxBucketCount != null && buckets.size() > maxBucketCount) {
return buckets.stream().limit(maxBucketCount).collect(Collectors.toCollection(TreeSet::new));
}

return buckets;
}

Expand Down Expand Up @@ -210,6 +220,11 @@ public Double getMaximumExpectedValueAsDouble() {
return maximumExpectedValue;
}

@Nullable
public Integer getMaxBucketCount() {
return maxBucketCount;
}

/**
* Statistics like max, percentiles, and histogram counts decay over time to give
* greater weight to recent samples (exception: histogram counts are cumulative for
Expand Down Expand Up @@ -453,6 +468,16 @@ public Builder bufferLength(@Nullable Integer bufferLength) {
return this;
}

/**
* Restricts the number of buckets/bin ranges used in histogram.
* @param maxBucketCount maximum number of buckets
* @return This buffer
*/
public Builder maxBucketCount(@Nullable Integer maxBucketCount) {
config.maxBucketCount = maxBucketCount;
return this;
}

/**
* @return A new immutable distribution configuration.
*/
Expand Down Expand Up @@ -489,6 +514,10 @@ private void validate(DistributionStatisticConfig distributionStatisticConfig) {
+ ").");
}

if (config.maxBucketCount != null && config.maxBucketCount <= 0) {
rejectConfig("maxBucketCount (" + config.maxBucketCount + ") must be greater than zero");
}

if (distributionStatisticConfig.getServiceLevelObjectiveBoundaries() != null) {
for (double slo : distributionStatisticConfig.getServiceLevelObjectiveBoundaries()) {
if (slo <= 0) {
Expand Down

0 comments on commit 6be37b0

Please sign in to comment.