mirror of
https://github.com/prometheus/prometheus.git
synced 2025-10-23 21:41:00 +02:00
tsdb: Fix appended sample count metrics when converting float staleness markers to histograms (#17241)
tsdb: Fix appended sample count metrics when converting histogram staleness markers Signed-off-by: Patryk Prus <p@trykpr.us> Signed-off-by: Björn Rabenstein <github@rabenste.in> Co-authored-by: Björn Rabenstein <github@rabenste.in>
This commit is contained in:
parent
cc7b1de372
commit
dc3e6af91a
@ -1331,6 +1331,9 @@ func (a *headAppender) commitFloats(b *appendBatch, acc *appenderCommitContext)
|
||||
H: &histogram.Histogram{Sum: s.V},
|
||||
})
|
||||
b.histogramSeries = append(b.histogramSeries, series)
|
||||
// This sample was counted as a float but is now a histogram.
|
||||
acc.floatsAppended--
|
||||
acc.histogramsAppended++
|
||||
series.Unlock()
|
||||
continue
|
||||
case series.lastFloatHistogramValue != nil:
|
||||
@ -1340,6 +1343,9 @@ func (a *headAppender) commitFloats(b *appendBatch, acc *appenderCommitContext)
|
||||
FH: &histogram.FloatHistogram{Sum: s.V},
|
||||
})
|
||||
b.floatHistogramSeries = append(b.floatHistogramSeries, series)
|
||||
// This sample was counted as a float but is now a float histogram.
|
||||
acc.floatsAppended--
|
||||
acc.histogramsAppended++
|
||||
series.Unlock()
|
||||
continue
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ import (
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
prom_testutil "github.com/prometheus/client_golang/prometheus/testutil"
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
"github.com/prometheus/common/promslog"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/atomic"
|
||||
@ -7256,3 +7257,92 @@ func TestHead_NumStaleSeries(t *testing.T) {
|
||||
appendFloatHistogram(series8, 400, staleFH)
|
||||
verifySeriesCounts(4, 5)
|
||||
}
|
||||
|
||||
// TestHistogramStalenessConversionMetrics verifies that staleness marker conversion correctly
|
||||
// increments the right appender metrics for both histogram and float histogram scenarios.
|
||||
func TestHistogramStalenessConversionMetrics(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
setupHistogram func(app storage.Appender, lbls labels.Labels) error
|
||||
}{
|
||||
{
|
||||
name: "float_staleness_to_histogram",
|
||||
setupHistogram: func(app storage.Appender, lbls labels.Labels) error {
|
||||
_, err := app.AppendHistogram(0, lbls, 1000, tsdbutil.GenerateTestHistograms(1)[0], nil)
|
||||
return err
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "float_staleness_to_float_histogram",
|
||||
setupHistogram: func(app storage.Appender, lbls labels.Labels) error {
|
||||
_, err := app.AppendHistogram(0, lbls, 1000, nil, tsdbutil.GenerateTestFloatHistograms(1)[0])
|
||||
return err
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
head, _ := newTestHead(t, 1000, compression.None, false)
|
||||
defer func() {
|
||||
require.NoError(t, head.Close())
|
||||
}()
|
||||
|
||||
lbls := labels.FromStrings("name", tc.name)
|
||||
|
||||
// Helper to get counter values
|
||||
getSampleCounter := func(sampleType string) float64 {
|
||||
metric := &dto.Metric{}
|
||||
err := head.metrics.samplesAppended.WithLabelValues(sampleType).Write(metric)
|
||||
require.NoError(t, err)
|
||||
return metric.GetCounter().GetValue()
|
||||
}
|
||||
|
||||
// Step 1: Establish a series with histogram data
|
||||
app := head.Appender(context.Background())
|
||||
err := tc.setupHistogram(app, lbls)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, app.Commit())
|
||||
|
||||
// Step 2: Add a float staleness marker
|
||||
app = head.Appender(context.Background())
|
||||
_, err = app.Append(0, lbls, 2000, math.Float64frombits(value.StaleNaN))
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, app.Commit())
|
||||
|
||||
// Count what was actually stored by querying the series
|
||||
q, err := NewBlockQuerier(head, 0, 3000)
|
||||
require.NoError(t, err)
|
||||
defer q.Close()
|
||||
|
||||
ss := q.Select(context.Background(), false, nil, labels.MustNewMatcher(labels.MatchEqual, "name", tc.name))
|
||||
require.True(t, ss.Next())
|
||||
series := ss.At()
|
||||
|
||||
it := series.Iterator(nil)
|
||||
|
||||
actualFloatSamples := 0
|
||||
actualHistogramSamples := 0
|
||||
|
||||
for valType := it.Next(); valType != chunkenc.ValNone; valType = it.Next() {
|
||||
switch valType {
|
||||
case chunkenc.ValFloat:
|
||||
actualFloatSamples++
|
||||
case chunkenc.ValHistogram, chunkenc.ValFloatHistogram:
|
||||
actualHistogramSamples++
|
||||
}
|
||||
}
|
||||
require.NoError(t, it.Err())
|
||||
|
||||
// Verify what was actually stored - should be 0 floats, 2 histograms (original + converted staleness marker)
|
||||
require.Equal(t, 0, actualFloatSamples, "Should have 0 float samples stored")
|
||||
require.Equal(t, 2, actualHistogramSamples, "Should have 2 histogram samples: original + converted staleness marker")
|
||||
|
||||
// The metrics should match what was actually stored
|
||||
require.Equal(t, float64(actualFloatSamples), getSampleCounter(sampleMetricTypeFloat),
|
||||
"Float counter should match actual float samples stored")
|
||||
require.Equal(t, float64(actualHistogramSamples), getSampleCounter(sampleMetricTypeHistogram),
|
||||
"Histogram counter should match actual histogram samples stored")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user