Skip to content

Commit 3289a24

Browse files
authored
fix native histogram empty bucket marshal panic (#6595)
* fix native histogram empty bucket marshal panic Signed-off-by: yeya24 <[email protected]> * changelog Signed-off-by: yeya24 <[email protected]> --------- Signed-off-by: yeya24 <[email protected]>
1 parent 47a74e2 commit 3289a24

File tree

3 files changed

+100
-8
lines changed

3 files changed

+100
-8
lines changed

Diff for: CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
* [BUGFIX] Ingester: Fix labelset data race condition. #6573
1212
* [BUGFIX] Compactor: Cleaner should not put deletion marker for blocks with no-compact marker. #6576
1313
* [BUGFIX] Compactor: Cleaner would delete bucket index when there is no block in bucket store. #6577
14+
* [BUGFIX] Querier: Fix marshal native histogram with empty bucket when protobuf codec is enabled. #6595
1415

1516
## 1.19.0 in progress
1617

Diff for: pkg/querier/codec/protobuf_codec.go

+7-8
Original file line numberDiff line numberDiff line change
@@ -134,15 +134,13 @@ func getMatrixSampleStreams(data *v1.QueryData) *[]tripperware.SampleStream {
134134
if sampleStream.Histograms[j].H.ZeroCount > 0 {
135135
bucketsLen = len(sampleStream.Histograms[j].H.NegativeBuckets) + len(sampleStream.Histograms[j].H.PositiveBuckets) + 1
136136
}
137-
buckets := make([]*tripperware.HistogramBucket, bucketsLen)
138137
it := sampleStream.Histograms[j].H.AllBucketIterator()
139-
getBuckets(buckets, it)
140138
histograms[j] = tripperware.SampleHistogramPair{
141139
TimestampMs: sampleStream.Histograms[j].T,
142140
Histogram: tripperware.SampleHistogram{
143141
Count: sampleStream.Histograms[j].H.Count,
144142
Sum: sampleStream.Histograms[j].H.Sum,
145-
Buckets: buckets,
143+
Buckets: getBuckets(bucketsLen, it),
146144
},
147145
}
148146
}
@@ -192,22 +190,21 @@ func getVectorSamples(data *v1.QueryData, cortexInternal bool) *[]tripperware.Sa
192190
if sample.H.ZeroCount > 0 {
193191
bucketsLen = len(sample.H.NegativeBuckets) + len(sample.H.PositiveBuckets) + 1
194192
}
195-
buckets := make([]*tripperware.HistogramBucket, bucketsLen)
196193
it := sample.H.AllBucketIterator()
197-
getBuckets(buckets, it)
198194
vectorSamples[i].Histogram = &tripperware.SampleHistogramPair{
199195
TimestampMs: sample.T,
200196
Histogram: tripperware.SampleHistogram{
201197
Count: sample.H.Count,
202198
Sum: sample.H.Sum,
203-
Buckets: buckets,
199+
Buckets: getBuckets(bucketsLen, it),
204200
},
205201
}
206202
}
207203
return &vectorSamples
208204
}
209205

210-
func getBuckets(bucketsList []*tripperware.HistogramBucket, it histogram.BucketIterator[float64]) {
206+
func getBuckets(bucketsLen int, it histogram.BucketIterator[float64]) []*tripperware.HistogramBucket {
207+
buckets := make([]*tripperware.HistogramBucket, bucketsLen)
211208
bucketIdx := 0
212209
for it.Next() {
213210
bucket := it.At()
@@ -226,14 +223,16 @@ func getBuckets(bucketsList []*tripperware.HistogramBucket, it histogram.BucketI
226223
boundaries = 0 // Inclusive only on upper end AKA left open.
227224
}
228225
}
229-
bucketsList[bucketIdx] = &tripperware.HistogramBucket{
226+
buckets[bucketIdx] = &tripperware.HistogramBucket{
230227
Boundaries: int32(boundaries),
231228
Lower: bucket.Lower,
232229
Upper: bucket.Upper,
233230
Count: bucket.Count,
234231
}
235232
bucketIdx += 1
236233
}
234+
buckets = buckets[:bucketIdx]
235+
return buckets
237236
}
238237

239238
func getStats(builtin *stats.BuiltinStats) *tripperware.PrometheusResponseSamplesStats {

Diff for: pkg/querier/codec/protobuf_codec_test.go

+92
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,17 @@ func TestProtobufCodec_Encode(t *testing.T) {
3939
}
4040
testProtoHistogram := cortexpb.FloatHistogramToHistogramProto(1000, testFloatHistogram)
4141

42+
floatHistogramWithEmptyBucket := &histogram.FloatHistogram{
43+
CounterResetHint: 0,
44+
Schema: 1,
45+
ZeroThreshold: 0.01,
46+
ZeroCount: 0,
47+
Count: 0,
48+
Sum: 1,
49+
PositiveSpans: []histogram.Span{{Offset: 0, Length: 1}},
50+
PositiveBuckets: []float64{0},
51+
}
52+
4253
tests := []struct {
4354
name string
4455
data *v1.QueryData
@@ -287,6 +298,47 @@ func TestProtobufCodec_Encode(t *testing.T) {
287298
},
288299
},
289300
},
301+
{
302+
name: "matrix with histogram and not cortex internal, empty bucket",
303+
data: &v1.QueryData{
304+
ResultType: parser.ValueTypeMatrix,
305+
Result: promql.Matrix{
306+
promql.Series{
307+
Histograms: []promql.HPoint{{H: floatHistogramWithEmptyBucket, T: 1000}},
308+
Metric: labels.FromStrings("__name__", "foo"),
309+
},
310+
},
311+
},
312+
expected: &tripperware.PrometheusResponse{
313+
Status: tripperware.StatusSuccess,
314+
Data: tripperware.PrometheusData{
315+
ResultType: model.ValMatrix.String(),
316+
Result: tripperware.PrometheusQueryResult{
317+
Result: &tripperware.PrometheusQueryResult_Matrix{
318+
Matrix: &tripperware.Matrix{
319+
SampleStreams: []tripperware.SampleStream{
320+
{
321+
Labels: []cortexpb.LabelAdapter{
322+
{Name: "__name__", Value: "foo"},
323+
},
324+
Histograms: []tripperware.SampleHistogramPair{
325+
{
326+
TimestampMs: 1000,
327+
Histogram: tripperware.SampleHistogram{
328+
Count: 0,
329+
Sum: 1,
330+
Buckets: []*tripperware.HistogramBucket{},
331+
},
332+
},
333+
},
334+
},
335+
},
336+
},
337+
},
338+
},
339+
},
340+
},
341+
},
290342
{
291343
name: "vector with histogram and not cortex internal",
292344
data: &v1.QueryData{
@@ -376,6 +428,46 @@ func TestProtobufCodec_Encode(t *testing.T) {
376428
},
377429
},
378430
},
431+
{
432+
name: "vector with histogram with and not cortex internal, empty bucket",
433+
data: &v1.QueryData{
434+
ResultType: parser.ValueTypeVector,
435+
Result: promql.Vector{
436+
promql.Sample{
437+
Metric: labels.FromStrings("__name__", "foo"),
438+
T: 1000,
439+
H: floatHistogramWithEmptyBucket,
440+
},
441+
},
442+
},
443+
expected: &tripperware.PrometheusResponse{
444+
Status: tripperware.StatusSuccess,
445+
Data: tripperware.PrometheusData{
446+
ResultType: model.ValVector.String(),
447+
Result: tripperware.PrometheusQueryResult{
448+
Result: &tripperware.PrometheusQueryResult_Vector{
449+
Vector: &tripperware.Vector{
450+
Samples: []tripperware.Sample{
451+
{
452+
Labels: []cortexpb.LabelAdapter{
453+
{Name: "__name__", Value: "foo"},
454+
},
455+
Histogram: &tripperware.SampleHistogramPair{
456+
TimestampMs: 1000,
457+
Histogram: tripperware.SampleHistogram{
458+
Count: 0,
459+
Sum: 1,
460+
Buckets: []*tripperware.HistogramBucket{},
461+
},
462+
},
463+
},
464+
},
465+
},
466+
},
467+
},
468+
},
469+
},
470+
},
379471
{
380472
name: "vector with histogram and cortex internal",
381473
cortexInternal: true,

0 commit comments

Comments
 (0)