Skip to content

Commit abe540f

Browse files
committed
Encode sparse histograms in protobuf
Signed-off-by: beorn7 <[email protected]>
1 parent c98db4e commit abe540f

File tree

3 files changed

+35
-28
lines changed

3 files changed

+35
-28
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ require (
77
github.com/google/go-cmp v0.4.0 // indirect
88
github.com/json-iterator/go v1.1.9
99
github.com/kr/pretty v0.1.0 // indirect
10-
github.com/prometheus/client_model v0.2.0
10+
github.com/prometheus/client_model v0.2.1-0.20200406191659-4b803f3550a4
1111
github.com/prometheus/common v0.9.1
1212
github.com/prometheus/procfs v0.0.8
1313
github.com/stretchr/testify v1.4.0 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx
7373
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
7474
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
7575
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
76+
github.com/prometheus/client_model v0.2.1-0.20200406191659-4b803f3550a4 h1:7Ws+6l4/5eJPHAxe0Axwo4XJwSAA4i0ipEjuoLXWFyo=
77+
github.com/prometheus/client_model v0.2.1-0.20200406191659-4b803f3550a4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
7678
github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw=
7779
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
7880
github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U=

prometheus/histogram.go

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@
1414
package prometheus
1515

1616
import (
17-
"bytes"
1817
"fmt"
19-
"io"
2018
"math"
2119
"runtime"
2220
"sort"
@@ -215,7 +213,7 @@ func newHistogram(desc *Desc, opts HistogramOpts, labelValues ...string) Histogr
215213
h := &histogram{
216214
desc: desc,
217215
upperBounds: opts.Buckets,
218-
sparseResolution: opts.SparseBucketsResolution,
216+
sparseResolution: uint32(opts.SparseBucketsResolution),
219217
sparseThreshold: opts.SparseBucketsZeroThreshold,
220218
labelPairs: makeLabelPairs(desc, labelValues),
221219
counts: [2]*histogramCounts{{}, {}},
@@ -355,7 +353,7 @@ type histogram struct {
355353
upperBounds []float64
356354
labelPairs []*dto.LabelPair
357355
exemplars []atomic.Value // One more than buckets (to include +Inf), each a *dto.Exemplar.
358-
sparseResolution uint8
356+
sparseResolution uint32 // Instead of uint8 to be ready for protobuf encoding.
359357
sparseThreshold float64
360358

361359
now func() time.Time // To mock out time.Now() for testing.
@@ -400,9 +398,11 @@ func (h *histogram) Write(out *dto.Metric) error {
400398
}
401399

402400
his := &dto.Histogram{
403-
Bucket: make([]*dto.Bucket, len(h.upperBounds)),
404-
SampleCount: proto.Uint64(count),
405-
SampleSum: proto.Float64(math.Float64frombits(atomic.LoadUint64(&coldCounts.sumBits))),
401+
Bucket: make([]*dto.Bucket, len(h.upperBounds)),
402+
SampleCount: proto.Uint64(count),
403+
SampleSum: proto.Float64(math.Float64frombits(atomic.LoadUint64(&coldCounts.sumBits))),
404+
SbResolution: &h.sparseResolution,
405+
SbZeroThreshold: &h.sparseThreshold,
406406
}
407407
out.Histogram = his
408408
out.Label = h.labelPairs
@@ -452,38 +452,43 @@ func (h *histogram) Write(out *dto.Metric) error {
452452
coldCounts.sparseBucketsNegative.Range(addAndReset(&hotCounts.sparseBucketsNegative))
453453
}()
454454

455-
var buf bytes.Buffer
456-
// TODO(beorn7): encode zero bucket threshold and count.
457-
fmt.Println("Zero bucket:", zeroBucket) // DEBUG
458-
fmt.Println("Positive buckets:") // DEBUG
459-
if _, err := encodeSparseBuckets(&buf, &coldCounts.sparseBucketsPositive, zeroBucket); err != nil {
460-
return err
461-
}
462-
fmt.Println("Negative buckets:") // DEBUG
463-
if _, err := encodeSparseBuckets(&buf, &coldCounts.sparseBucketsNegative, zeroBucket); err != nil {
464-
return err
465-
}
455+
his.SbZeroCount = proto.Uint64(zeroBucket)
456+
his.SbNegative = makeSparseBuckets(&coldCounts.sparseBucketsNegative)
457+
his.SbPositive = makeSparseBuckets(&coldCounts.sparseBucketsPositive)
466458
}
467459
return nil
468460
}
469461

470-
func encodeSparseBuckets(w io.Writer, buckets *sync.Map, zeroBucket uint64) (n int, err error) {
471-
// TODO(beorn7): Add actual encoding of spare buckets.
462+
func makeSparseBuckets(buckets *sync.Map) *dto.SparseBuckets {
472463
var ii []int
473464
buckets.Range(func(k, v interface{}) bool {
474465
ii = append(ii, k.(int))
475466
return true
476467
})
477468
sort.Ints(ii)
478-
fmt.Println(len(ii), "buckets")
479-
var prev uint64
480-
for _, i := range ii {
469+
470+
if len(ii) == 0 {
471+
return nil
472+
}
473+
474+
sbs := dto.SparseBuckets{}
475+
var prevCount uint64
476+
var prevI int
477+
for n, i := range ii {
481478
v, _ := buckets.Load(i)
482-
current := atomic.LoadUint64(v.(*uint64))
483-
fmt.Printf("- %d: %d Δ=%d\n", i, current, int(current)-int(prev))
484-
prev = current
479+
count := atomic.LoadUint64(v.(*uint64))
480+
if n == 0 || i-prevI != 1 {
481+
sbs.Span = append(sbs.Span, &dto.SparseBuckets_Span{
482+
Offset: proto.Int(i - prevI),
483+
Length: proto.Uint32(1),
484+
})
485+
} else {
486+
*sbs.Span[len(sbs.Span)-1].Length++
487+
}
488+
sbs.Delta = append(sbs.Delta, int64(count)-int64(prevCount)) // TODO(beorn7): Do proper overflow handling.
489+
prevI, prevCount = i, count
485490
}
486-
return 0, nil
491+
return &sbs
487492
}
488493

489494
// addAndReset returns a function to be used with sync.Map.Range of spare

0 commit comments

Comments
 (0)