Skip to content

Commit

Permalink
add ExponentialBucketsRange function (#899)
Browse files Browse the repository at this point in the history
This function calculates exponential buckets with different arguments
than the existing ExponentialBuckets function. Instead of specifying the
start and factor, the user can specify the min and max bucket value. We
have been doing it this way internally at my company for some time.

Signed-off-by: Seth Bunce <[email protected]>
  • Loading branch information
sbunce authored Aug 12, 2021
1 parent 20eef74 commit 2261d5c
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 0 deletions.
28 changes: 28 additions & 0 deletions prometheus/histogram.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,34 @@ func ExponentialBuckets(start, factor float64, count int) []float64 {
return buckets
}

// ExponentialBucketsRange creates 'count' buckets, where the lowest bucket is
// 'min' and the highest bucket is 'max'. The final +Inf bucket is not counted
// and not included in the returned slice. The returned slice is meant to be
// used for the Buckets field of HistogramOpts.
//
// The function panics if 'count' is 0 or negative, if 'min' is 0 or negative.
func ExponentialBucketsRange(min, max float64, count int) []float64 {
if count < 1 {
panic("ExponentialBucketsRange count needs a positive count")
}
if min <= 0 {
panic("ExponentialBucketsRange min needs to be greater than 0")
}

// Formula for exponential buckets.
// max = min*growthFactor^(bucketCount-1)

// We know max/min and highest bucket. Solve for growthFactor.
growthFactor := math.Pow(max/min, 1.0/float64(count-1))

// Now that we know growthFactor, solve for each bucket.
buckets := make([]float64, count)
for i := 1; i <= count; i++ {
buckets[i-1] = min * math.Pow(growthFactor, float64(i-1))
}
return buckets
}

// HistogramOpts bundles the options for creating a Histogram metric. It is
// mandatory to set Name to a non-empty string. All other fields are optional
// and can safely be left at their zero value, although it is strongly
Expand Down
10 changes: 10 additions & 0 deletions prometheus/histogram_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,16 @@ func TestBuckets(t *testing.T) {
if !reflect.DeepEqual(got, want) {
t.Errorf("exponential buckets: got %v, want %v", got, want)
}

got = ExponentialBucketsRange(1, 100, 10)
want = []float64{1.0, 1.6681005372000588, 2.782559402207125,
4.641588833612779, 7.742636826811273, 12.915496650148842,
21.544346900318846, 35.93813663804629, 59.94842503189414,
100.00000000000007,
}
if !reflect.DeepEqual(got, want) {
t.Errorf("exponential buckets range: got %v, want %v", got, want)
}
}

func TestHistogramAtomicObserve(t *testing.T) {
Expand Down

0 comments on commit 2261d5c

Please sign in to comment.