Skip to content

Commit 8cbcd40

Browse files
committed
histograms: Move to new exposition protobuf format
Note that this is an incompatible change. To scrape this new format, the Prometheus server needs to be updated at the same time. PR incoming. Signed-off-by: beorn7 <[email protected]>
1 parent 6141a07 commit 8cbcd40

File tree

4 files changed

+59
-55
lines changed

4 files changed

+59
-55
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ require (
88
github.com/davecgh/go-spew v1.1.1
99
github.com/golang/protobuf v1.5.2
1010
github.com/json-iterator/go v1.1.12
11-
github.com/prometheus/client_model v0.2.1-0.20210624201024-61b6c1aac064
11+
github.com/prometheus/client_model v0.2.1-0.20220719122737-1f8dcad1221e
1212
github.com/prometheus/common v0.35.0
1313
github.com/prometheus/procfs v0.7.3
1414
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
135135
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
136136
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
137137
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
138-
github.com/prometheus/client_model v0.2.1-0.20210624201024-61b6c1aac064 h1:Kyx21CLOfWDA4e2TcOcupRl2g/Bmddu0AL0hR1BldEw=
139-
github.com/prometheus/client_model v0.2.1-0.20210624201024-61b6c1aac064/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
138+
github.com/prometheus/client_model v0.2.1-0.20220719122737-1f8dcad1221e h1:KjoQdMEQmNC8smQ731iHAXnbFbApg4uu60fNcWHs3Bk=
139+
github.com/prometheus/client_model v0.2.1-0.20220719122737-1f8dcad1221e/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
140140
github.com/prometheus/common v0.35.0 h1:Eyr+Pw2VymWejHqCugNaQXkAi6KayVNxaHeu6khmFBE=
141141
github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
142142
github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=

prometheus/histogram.go

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -382,19 +382,20 @@ type HistogramOpts struct {
382382
Buckets []float64
383383

384384
// If SparseBucketsFactor is greater than one, sparse buckets are used
385-
// (in addition to the regular buckets, if defined above). Sparse
386-
// buckets are exponential buckets covering the whole float64 range
387-
// (with the exception of the “zero” bucket, see
388-
// SparseBucketsZeroThreshold below). From any one bucket to the next,
389-
// the width of the bucket grows by a constant factor.
390-
// SparseBucketsFactor provides an upper bound for this factor
391-
// (exception see below). The smaller SparseBucketsFactor, the more
392-
// buckets will be used and thus the more costly the histogram will
393-
// become. A generally good trade-off between cost and accuracy is a
394-
// value of 1.1 (each bucket is at most 10% wider than the previous
395-
// one), which will result in each power of two divided into 8 buckets
396-
// (e.g. there will be 8 buckets between 1 and 2, same as between 2 and
397-
// 4, and 4 and 8, etc.).
385+
// (in addition to the regular buckets, if defined above). A histogram
386+
// with sparse buckets will be ingested as a native histogram by a
387+
// Prometheus server with that feature enable. Sparse buckets are
388+
// exponential buckets covering the whole float64 range (with the
389+
// exception of the “zero” bucket, see SparseBucketsZeroThreshold
390+
// below). From any one bucket to the next, the width of the bucket
391+
// grows by a constant factor. SparseBucketsFactor provides an upper
392+
// bound for this factor (exception see below). The smaller
393+
// SparseBucketsFactor, the more buckets will be used and thus the more
394+
// costly the histogram will become. A generally good trade-off between
395+
// cost and accuracy is a value of 1.1 (each bucket is at most 10% wider
396+
// than the previous one), which will result in each power of two
397+
// divided into 8 buckets (e.g. there will be 8 buckets between 1 and 2,
398+
// same as between 2 and 4, and 4 and 8, etc.).
398399
//
399400
// Details about the actually used factor: The factor is calculated as
400401
// 2^(2^n), where n is an integer number between (and including) -8 and
@@ -723,18 +724,18 @@ func (h *histogram) Write(out *dto.Metric) error {
723724
his.Bucket = append(his.Bucket, b)
724725
}
725726
if h.sparseSchema > math.MinInt32 {
726-
his.SbZeroThreshold = proto.Float64(math.Float64frombits(atomic.LoadUint64(&coldCounts.sparseZeroThresholdBits)))
727-
his.SbSchema = proto.Int32(atomic.LoadInt32(&coldCounts.sparseSchema))
727+
his.ZeroThreshold = proto.Float64(math.Float64frombits(atomic.LoadUint64(&coldCounts.sparseZeroThresholdBits)))
728+
his.Schema = proto.Int32(atomic.LoadInt32(&coldCounts.sparseSchema))
728729
zeroBucket := atomic.LoadUint64(&coldCounts.sparseZeroBucket)
729730

730731
defer func() {
731732
coldCounts.sparseBucketsPositive.Range(addAndReset(&hotCounts.sparseBucketsPositive, &hotCounts.sparseBucketsNumber))
732733
coldCounts.sparseBucketsNegative.Range(addAndReset(&hotCounts.sparseBucketsNegative, &hotCounts.sparseBucketsNumber))
733734
}()
734735

735-
his.SbZeroCount = proto.Uint64(zeroBucket)
736-
his.SbNegative = makeSparseBuckets(&coldCounts.sparseBucketsNegative)
737-
his.SbPositive = makeSparseBuckets(&coldCounts.sparseBucketsPositive)
736+
his.ZeroCount = proto.Uint64(zeroBucket)
737+
his.NegativeSpan, his.NegativeDelta = makeSparseBuckets(&coldCounts.sparseBucketsNegative)
738+
his.PositiveSpan, his.PositiveDelta = makeSparseBuckets(&coldCounts.sparseBucketsPositive)
738739
}
739740
addAndResetCounts(hotCounts, coldCounts)
740741
return nil
@@ -1235,7 +1236,7 @@ func pickSparseSchema(bucketFactor float64) int32 {
12351236
}
12361237
}
12371238

1238-
func makeSparseBuckets(buckets *sync.Map) *dto.SparseBuckets {
1239+
func makeSparseBuckets(buckets *sync.Map) ([]*dto.BucketSpan, []int64) {
12391240
var ii []int
12401241
buckets.Range(func(k, v interface{}) bool {
12411242
ii = append(ii, k.(int))
@@ -1244,16 +1245,19 @@ func makeSparseBuckets(buckets *sync.Map) *dto.SparseBuckets {
12441245
sort.Ints(ii)
12451246

12461247
if len(ii) == 0 {
1247-
return nil
1248+
return nil, nil
12481249
}
12491250

1250-
sbs := dto.SparseBuckets{}
1251-
var prevCount int64
1252-
var nextI int
1251+
var (
1252+
spans []*dto.BucketSpan
1253+
deltas []int64
1254+
prevCount int64
1255+
nextI int
1256+
)
12531257

12541258
appendDelta := func(count int64) {
1255-
*sbs.Span[len(sbs.Span)-1].Length++
1256-
sbs.Delta = append(sbs.Delta, count-prevCount)
1259+
*spans[len(spans)-1].Length++
1260+
deltas = append(deltas, count-prevCount)
12571261
prevCount = count
12581262
}
12591263

@@ -1270,7 +1274,7 @@ func makeSparseBuckets(buckets *sync.Map) *dto.SparseBuckets {
12701274
// We have to create a new span, either because we are
12711275
// at the very beginning, or because we have found a gap
12721276
// of more than two buckets.
1273-
sbs.Span = append(sbs.Span, &dto.SparseBuckets_Span{
1277+
spans = append(spans, &dto.BucketSpan{
12741278
Offset: proto.Int32(iDelta),
12751279
Length: proto.Uint32(0),
12761280
})
@@ -1284,7 +1288,7 @@ func makeSparseBuckets(buckets *sync.Map) *dto.SparseBuckets {
12841288
appendDelta(count)
12851289
nextI = i + 1
12861290
}
1287-
return &sbs
1291+
return spans, deltas
12881292
}
12891293

12901294
// addToSparseBucket increments the sparse bucket at key by the provided

0 commit comments

Comments
 (0)