diff --git a/pkg/translator/prometheusremotewrite/histograms.go b/pkg/translator/prometheusremotewrite/histograms.go index ec25abcefcca..0581e8f93552 100644 --- a/pkg/translator/prometheusremotewrite/histograms.go +++ b/pkg/translator/prometheusremotewrite/histograms.go @@ -96,7 +96,11 @@ func exponentialToNativeHistogram(p pmetric.ExponentialHistogramDataPoint) (prom if p.HasSum() { h.Sum = p.Sum() } - h.Count = &prompb.Histogram_CountInt{CountInt: p.Count()} + if scaleDown > 0 { + h.Count = &prompb.Histogram_CountInt{CountInt: nativeHistogramBucketCount(&h)} + } else { + h.Count = &prompb.Histogram_CountInt{CountInt: p.Count()} + } } return h, nil } @@ -194,3 +198,13 @@ func convertBucketsLayout(buckets pmetric.ExponentialHistogramDataPointBuckets, return spans, deltas } + +func nativeHistogramBucketCount(h *prompb.Histogram) (count uint64) { + for _, span := range h.PositiveSpans { + count += uint64(span.Length) + } + for _, span := range h.NegativeSpans { + count += uint64(span.Length) + } + return +} diff --git a/pkg/translator/prometheusremotewrite/histograms_test.go b/pkg/translator/prometheusremotewrite/histograms_test.go index d6a29e2738f7..82875cbcdfc0 100644 --- a/pkg/translator/prometheusremotewrite/histograms_test.go +++ b/pkg/translator/prometheusremotewrite/histograms_test.go @@ -536,7 +536,7 @@ func TestExponentialToNativeHistogram(t *testing.T) { }, wantNativeHist: func() prompb.Histogram { return prompb.Histogram{ - Count: &prompb.Histogram_CountInt{CountInt: 6}, + Count: &prompb.Histogram_CountInt{CountInt: 4}, Sum: 10.1, Schema: 8, ZeroThreshold: defaultZeroThreshold, @@ -552,6 +552,7 @@ func TestExponentialToNativeHistogram(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + validateHistogramCount(t, tt.exponentialHist()) // Sanity check. got, err := exponentialToNativeHistogram(tt.exponentialHist()) if tt.wantErrMessage != "" { assert.ErrorContains(t, err, tt.wantErrMessage) @@ -560,10 +561,29 @@ func TestExponentialToNativeHistogram(t *testing.T) { require.NoError(t, err) assert.Equal(t, tt.wantNativeHist(), got) + validateNativeHistogramCount(t, got) }) } } +func validateHistogramCount(t *testing.T, h pmetric.ExponentialHistogramDataPoint) { + require.Equal(t, h.Count(), uint64(h.Positive().BucketCounts().Len())+uint64(h.Negative().BucketCounts().Len())) +} + +func validateNativeHistogramCount(t *testing.T, h prompb.Histogram) { + require.NotNil(t, h.Count) + require.IsType(t, &prompb.Histogram_CountInt{}, h.Count) + want := h.Count.(*prompb.Histogram_CountInt).CountInt + actualCount := uint64(0) + for _, span := range h.PositiveSpans { + actualCount += uint64(span.Length) + } + for _, span := range h.NegativeSpans { + actualCount += uint64(span.Length) + } + assert.Equal(t, want, actualCount) +} + func TestAddSingleExponentialHistogramDataPoint(t *testing.T) { tests := []struct { name string