From 0e3f35324b46010b0f6363d01e592eebad1a80ad Mon Sep 17 00:00:00 2001 From: beorn7 Date: Thu, 13 Jul 2023 14:16:10 +0200 Subject: [PATCH 1/2] scrape: Enable ingestion of multiple exemplars per sample This has become a requirement for native histograms, as a single histogram sample commonly has many buckets, so that providing many exemplars makes sense. Since OM text doesn't support native histograms yet, the test had to be expanded to also support protobuf test cases. Signed-off-by: beorn7 --- model/textparse/interface.go | 4 +- model/textparse/openmetricsparse.go | 8 +- scrape/scrape.go | 2 +- scrape/scrape_test.go | 144 ++++++++++++++++++++++++++-- tsdb/exemplar.go | 4 +- 5 files changed, 147 insertions(+), 15 deletions(-) diff --git a/model/textparse/interface.go b/model/textparse/interface.go index efa581410f..38903afc96 100644 --- a/model/textparse/interface.go +++ b/model/textparse/interface.go @@ -59,7 +59,9 @@ type Parser interface { Metric(l *labels.Labels) string // Exemplar writes the exemplar of the current sample into the passed - // exemplar. It returns if an exemplar exists or not. + // exemplar. It can be called repeatedly to retrieve multiple exemplars + // for the same sample. It returns false once all exemplars are + // retrieved (including the case where no exemplars exist at all). Exemplar(l *exemplar.Exemplar) bool // Next advances the parser to the next sample. It returns false if no diff --git a/model/textparse/openmetricsparse.go b/model/textparse/openmetricsparse.go index c17d40020a..e0833636f1 100644 --- a/model/textparse/openmetricsparse.go +++ b/model/textparse/openmetricsparse.go @@ -174,8 +174,10 @@ func (p *OpenMetricsParser) Metric(l *labels.Labels) string { return s } -// Exemplar writes the exemplar of the current sample into the passed -// exemplar. It returns the whether an exemplar exists. +// Exemplar writes the exemplar of the current sample into the passed exemplar. +// It returns whether an exemplar exists. As OpenMetrics only ever has one +// exemplar per sample, every call after the first (for the same sample) will +// always return false. func (p *OpenMetricsParser) Exemplar(e *exemplar.Exemplar) bool { if len(p.exemplar) == 0 { return false @@ -204,6 +206,8 @@ func (p *OpenMetricsParser) Exemplar(e *exemplar.Exemplar) bool { p.builder.Sort() e.Labels = p.builder.Labels() + // Wipe exemplar so that future calls return false. + p.exemplar = p.exemplar[:0] return true } diff --git a/scrape/scrape.go b/scrape/scrape.go index ec65c5ad9b..df729b4489 100644 --- a/scrape/scrape.go +++ b/scrape/scrape.go @@ -1685,7 +1685,7 @@ loop: // number of samples remaining after relabeling. added++ - if hasExemplar := p.Exemplar(&e); hasExemplar { + for hasExemplar := p.Exemplar(&e); hasExemplar; hasExemplar = p.Exemplar(&e) { if !e.HasTs { e.Ts = t } diff --git a/scrape/scrape_test.go b/scrape/scrape_test.go index 6c45c26b42..72e22fd0dd 100644 --- a/scrape/scrape_test.go +++ b/scrape/scrape_test.go @@ -17,6 +17,7 @@ import ( "bytes" "compress/gzip" "context" + "encoding/binary" "fmt" "io" "math" @@ -29,6 +30,7 @@ import ( "time" "github.com/go-kit/log" + "github.com/gogo/protobuf/proto" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" dto "github.com/prometheus/client_model/go" @@ -39,6 +41,7 @@ import ( "github.com/prometheus/prometheus/config" "github.com/prometheus/prometheus/discovery/targetgroup" "github.com/prometheus/prometheus/model/exemplar" + "github.com/prometheus/prometheus/model/histogram" "github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/model/relabel" "github.com/prometheus/prometheus/model/textparse" @@ -1980,15 +1983,18 @@ func TestScrapeLoopAppendExemplar(t *testing.T) { tests := []struct { title string scrapeText string + contentType string discoveryLabels []string - samples []sample + floats []sample + histograms []histogramSample exemplars []exemplar.Exemplar }{ { title: "Metric without exemplars", scrapeText: "metric_total{n=\"1\"} 0\n# EOF", + contentType: "application/openmetrics-text", discoveryLabels: []string{"n", "2"}, - samples: []sample{{ + floats: []sample{{ metric: labels.FromStrings("__name__", "metric_total", "exported_n", "1", "n", "2"), v: 0, }}, @@ -1996,8 +2002,9 @@ func TestScrapeLoopAppendExemplar(t *testing.T) { { title: "Metric with exemplars", scrapeText: "metric_total{n=\"1\"} 0 # {a=\"abc\"} 1.0\n# EOF", + contentType: "application/openmetrics-text", discoveryLabels: []string{"n", "2"}, - samples: []sample{{ + floats: []sample{{ metric: labels.FromStrings("__name__", "metric_total", "exported_n", "1", "n", "2"), v: 0, }}, @@ -2008,8 +2015,9 @@ func TestScrapeLoopAppendExemplar(t *testing.T) { { title: "Metric with exemplars and TS", scrapeText: "metric_total{n=\"1\"} 0 # {a=\"abc\"} 1.0 10000\n# EOF", + contentType: "application/openmetrics-text", discoveryLabels: []string{"n", "2"}, - samples: []sample{{ + floats: []sample{{ metric: labels.FromStrings("__name__", "metric_total", "exported_n", "1", "n", "2"), v: 0, }}, @@ -2022,7 +2030,8 @@ func TestScrapeLoopAppendExemplar(t *testing.T) { scrapeText: `metric_total{n="1"} 1 # {t="1"} 1.0 10000 metric_total{n="2"} 2 # {t="2"} 2.0 20000 # EOF`, - samples: []sample{{ + contentType: "application/openmetrics-text", + floats: []sample{{ metric: labels.FromStrings("__name__", "metric_total", "n", "1"), v: 1, }, { @@ -2034,6 +2043,104 @@ metric_total{n="2"} 2 # {t="2"} 2.0 20000 {Labels: labels.FromStrings("t", "2"), Value: 2, Ts: 20000000, HasTs: true}, }, }, + { + title: "Native histogram with two exemplars", + scrapeText: `name: "test_histogram" +help: "Test histogram with many buckets removed to keep it manageable in size." +type: HISTOGRAM +metric: < + histogram: < + sample_count: 175 + sample_sum: 0.0008280461746287094 + bucket: < + cumulative_count: 2 + upper_bound: -0.0004899999999999998 + > + bucket: < + cumulative_count: 4 + upper_bound: -0.0003899999999999998 + exemplar: < + label: < + name: "dummyID" + value: "59727" + > + value: -0.00039 + timestamp: < + seconds: 1625851155 + nanos: 146848499 + > + > + > + bucket: < + cumulative_count: 16 + upper_bound: -0.0002899999999999998 + exemplar: < + label: < + name: "dummyID" + value: "5617" + > + value: -0.00029 + > + > + schema: 3 + zero_threshold: 2.938735877055719e-39 + zero_count: 2 + negative_span: < + offset: -162 + length: 1 + > + negative_span: < + offset: 23 + length: 4 + > + negative_delta: 1 + negative_delta: 3 + negative_delta: -2 + negative_delta: -1 + negative_delta: 1 + positive_span: < + offset: -161 + length: 1 + > + positive_span: < + offset: 8 + length: 3 + > + positive_delta: 1 + positive_delta: 2 + positive_delta: -1 + positive_delta: -1 + > + timestamp_ms: 1234568 +> + +`, + contentType: "application/vnd.google.protobuf", + histograms: []histogramSample{{ + t: 1234568, + h: &histogram.Histogram{ + Count: 175, + ZeroCount: 2, + Sum: 0.0008280461746287094, + ZeroThreshold: 2.938735877055719e-39, + Schema: 3, + PositiveSpans: []histogram.Span{ + {Offset: -161, Length: 1}, + {Offset: 8, Length: 3}, + }, + NegativeSpans: []histogram.Span{ + {Offset: -162, Length: 1}, + {Offset: 23, Length: 4}, + }, + PositiveBuckets: []int64{1, 2, -1, -1}, + NegativeBuckets: []int64{1, 3, -2, -1, 1}, + }, + }}, + exemplars: []exemplar.Exemplar{ + {Labels: labels.FromStrings("dummyID", "59727"), Value: -0.00039, Ts: 1625851155146, HasTs: true}, + {Labels: labels.FromStrings("dummyID", "5617"), Value: -0.00029, Ts: 1234568, HasTs: false}, + }, + }, } for _, test := range tests { @@ -2069,8 +2176,8 @@ metric_total{n="2"} 2 # {t="2"} 2.0 20000 now := time.Now() - for i := range test.samples { - test.samples[i].t = timestamp.FromTime(now) + for i := range test.floats { + test.floats[i].t = timestamp.FromTime(now) } // We need to set the timestamp for expected exemplars that does not have a timestamp. @@ -2080,10 +2187,29 @@ metric_total{n="2"} 2 # {t="2"} 2.0 20000 } } - _, _, _, err := sl.append(app, []byte(test.scrapeText), "application/openmetrics-text", now) + buf := &bytes.Buffer{} + if test.contentType == "application/vnd.google.protobuf" { + // In case of protobuf, we have to create the binary representation. + pb := &dto.MetricFamily{} + // From text to proto message. + require.NoError(t, proto.UnmarshalText(test.scrapeText, pb)) + // From proto message to binary protobuf. + protoBuf, err := proto.Marshal(pb) + require.NoError(t, err) + + // Write first length, then binary protobuf. + varintBuf := binary.AppendUvarint(nil, uint64(len(protoBuf))) + buf.Write(varintBuf) + buf.Write(protoBuf) + } else { + buf.WriteString(test.scrapeText) + } + + _, _, _, err := sl.append(app, buf.Bytes(), test.contentType, now) require.NoError(t, err) require.NoError(t, app.Commit()) - require.Equal(t, test.samples, app.result) + require.Equal(t, test.floats, app.result) + require.Equal(t, test.histograms, app.resultHistograms) require.Equal(t, test.exemplars, app.resultExemplars) }) } diff --git a/tsdb/exemplar.go b/tsdb/exemplar.go index bf401da3ce..d4c0505cc1 100644 --- a/tsdb/exemplar.go +++ b/tsdb/exemplar.go @@ -365,8 +365,8 @@ func (ce *CircularExemplarStorage) AddExemplar(l labels.Labels, e exemplar.Exemp if prev := ce.exemplars[ce.nextIndex]; prev == nil { ce.exemplars[ce.nextIndex] = &circularBufferEntry{} } else { - // There exists exemplar already on this ce.nextIndex entry, drop it, to make place - // for others. + // There exists an exemplar already on this ce.nextIndex entry, + // drop it, to make place for others. var buf [1024]byte prevLabels := prev.ref.seriesLabels.Bytes(buf[:]) if prev.next == noExemplar { From 536a487af456abc66b90a4307388619d26209034 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Thu, 13 Jul 2023 14:27:51 +0200 Subject: [PATCH 2/2] scrape: Refactor names of float samples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Continue to remove confusion that histogram samples are also samples and histogram values are also values etc. by renaming float values and float samples using the same schema as for histograms. Concretely: - result → resultFloats (corresponding to resultHistograms) - pendingResult → pendingFloats (corresponding to pendingHistograms) - rolledbackResult → rolledbackFloats (corresponding to rolledbackHistograms) - sample → floatSample (corresponding to histogramSample) This also order the fields in `collectResultAppender` more consistently. Signed-off-by: beorn7 --- scrape/helpers_test.go | 40 ++++++------ scrape/scrape_test.go | 134 ++++++++++++++++++++--------------------- 2 files changed, 87 insertions(+), 87 deletions(-) diff --git a/scrape/helpers_test.go b/scrape/helpers_test.go index 4862886e5e..c580a50510 100644 --- a/scrape/helpers_test.go +++ b/scrape/helpers_test.go @@ -53,10 +53,10 @@ func (a nopAppender) UpdateMetadata(storage.SeriesRef, labels.Labels, metadata.M func (a nopAppender) Commit() error { return nil } func (a nopAppender) Rollback() error { return nil } -type sample struct { +type floatSample struct { metric labels.Labels t int64 - v float64 + f float64 } type histogramSample struct { @@ -69,23 +69,23 @@ type histogramSample struct { // It can be used as its zero value or be backed by another appender it writes samples through. type collectResultAppender struct { next storage.Appender - result []sample - pendingResult []sample - rolledbackResult []sample - pendingExemplars []exemplar.Exemplar - resultExemplars []exemplar.Exemplar + resultFloats []floatSample + pendingFloats []floatSample + rolledbackFloats []floatSample resultHistograms []histogramSample pendingHistograms []histogramSample rolledbackHistograms []histogramSample - pendingMetadata []metadata.Metadata + resultExemplars []exemplar.Exemplar + pendingExemplars []exemplar.Exemplar resultMetadata []metadata.Metadata + pendingMetadata []metadata.Metadata } func (a *collectResultAppender) Append(ref storage.SeriesRef, lset labels.Labels, t int64, v float64) (storage.SeriesRef, error) { - a.pendingResult = append(a.pendingResult, sample{ + a.pendingFloats = append(a.pendingFloats, floatSample{ metric: lset, t: t, - v: v, + f: v, }) if ref == 0 { @@ -133,11 +133,11 @@ func (a *collectResultAppender) UpdateMetadata(ref storage.SeriesRef, l labels.L } func (a *collectResultAppender) Commit() error { - a.result = append(a.result, a.pendingResult...) + a.resultFloats = append(a.resultFloats, a.pendingFloats...) a.resultExemplars = append(a.resultExemplars, a.pendingExemplars...) a.resultHistograms = append(a.resultHistograms, a.pendingHistograms...) a.resultMetadata = append(a.resultMetadata, a.pendingMetadata...) - a.pendingResult = nil + a.pendingFloats = nil a.pendingExemplars = nil a.pendingHistograms = nil a.pendingMetadata = nil @@ -148,9 +148,9 @@ func (a *collectResultAppender) Commit() error { } func (a *collectResultAppender) Rollback() error { - a.rolledbackResult = a.pendingResult + a.rolledbackFloats = a.pendingFloats a.rolledbackHistograms = a.pendingHistograms - a.pendingResult = nil + a.pendingFloats = nil a.pendingHistograms = nil if a.next == nil { return nil @@ -160,14 +160,14 @@ func (a *collectResultAppender) Rollback() error { func (a *collectResultAppender) String() string { var sb strings.Builder - for _, s := range a.result { - sb.WriteString(fmt.Sprintf("committed: %s %f %d\n", s.metric, s.v, s.t)) + for _, s := range a.resultFloats { + sb.WriteString(fmt.Sprintf("committed: %s %f %d\n", s.metric, s.f, s.t)) } - for _, s := range a.pendingResult { - sb.WriteString(fmt.Sprintf("pending: %s %f %d\n", s.metric, s.v, s.t)) + for _, s := range a.pendingFloats { + sb.WriteString(fmt.Sprintf("pending: %s %f %d\n", s.metric, s.f, s.t)) } - for _, s := range a.rolledbackResult { - sb.WriteString(fmt.Sprintf("rolledback: %s %f %d\n", s.metric, s.v, s.t)) + for _, s := range a.rolledbackFloats { + sb.WriteString(fmt.Sprintf("rolledback: %s %f %d\n", s.metric, s.f, s.t)) } return sb.String() } diff --git a/scrape/scrape_test.go b/scrape/scrape_test.go index 72e22fd0dd..3f119b94dd 100644 --- a/scrape/scrape_test.go +++ b/scrape/scrape_test.go @@ -740,12 +740,12 @@ func TestScrapeLoopStop(t *testing.T) { // We expected 1 actual sample for each scrape plus 5 for report samples. // At least 2 scrapes were made, plus the final stale markers. - if len(appender.result) < 6*3 || len(appender.result)%6 != 0 { - t.Fatalf("Expected at least 3 scrapes with 6 samples each, got %d samples", len(appender.result)) + if len(appender.resultFloats) < 6*3 || len(appender.resultFloats)%6 != 0 { + t.Fatalf("Expected at least 3 scrapes with 6 samples each, got %d samples", len(appender.resultFloats)) } // All samples in a scrape must have the same timestamp. var ts int64 - for i, s := range appender.result { + for i, s := range appender.resultFloats { switch { case i%6 == 0: ts = s.t @@ -754,9 +754,9 @@ func TestScrapeLoopStop(t *testing.T) { } } // All samples from the last scrape must be stale markers. - for _, s := range appender.result[len(appender.result)-5:] { - if !value.IsStaleNaN(s.v) { - t.Fatalf("Appended last sample not as expected. Wanted: stale NaN Got: %x", math.Float64bits(s.v)) + for _, s := range appender.resultFloats[len(appender.resultFloats)-5:] { + if !value.IsStaleNaN(s.f) { + t.Fatalf("Appended last sample not as expected. Wanted: stale NaN Got: %x", math.Float64bits(s.f)) } } } @@ -1192,10 +1192,10 @@ func TestScrapeLoopRunCreatesStaleMarkersOnFailedScrape(t *testing.T) { // 1 successfully scraped sample, 1 stale marker after first fail, 5 report samples for // each scrape successful or not. - require.Equal(t, 27, len(appender.result), "Appended samples not as expected:\n%s", appender) - require.Equal(t, 42.0, appender.result[0].v, "Appended first sample not as expected") - require.True(t, value.IsStaleNaN(appender.result[6].v), - "Appended second sample not as expected. Wanted: stale NaN Got: %x", math.Float64bits(appender.result[6].v)) + require.Equal(t, 27, len(appender.resultFloats), "Appended samples not as expected:\n%s", appender) + require.Equal(t, 42.0, appender.resultFloats[0].f, "Appended first sample not as expected") + require.True(t, value.IsStaleNaN(appender.resultFloats[6].f), + "Appended second sample not as expected. Wanted: stale NaN Got: %x", math.Float64bits(appender.resultFloats[6].f)) } func TestScrapeLoopRunCreatesStaleMarkersOnParseFailure(t *testing.T) { @@ -1257,10 +1257,10 @@ func TestScrapeLoopRunCreatesStaleMarkersOnParseFailure(t *testing.T) { // 1 successfully scraped sample, 1 stale marker after first fail, 5 report samples for // each scrape successful or not. - require.Equal(t, 17, len(appender.result), "Appended samples not as expected:\n%s", appender) - require.Equal(t, 42.0, appender.result[0].v, "Appended first sample not as expected") - require.True(t, value.IsStaleNaN(appender.result[6].v), - "Appended second sample not as expected. Wanted: stale NaN Got: %x", math.Float64bits(appender.result[6].v)) + require.Equal(t, 17, len(appender.resultFloats), "Appended samples not as expected:\n%s", appender) + require.Equal(t, 42.0, appender.resultFloats[0].f, "Appended first sample not as expected") + require.True(t, value.IsStaleNaN(appender.resultFloats[6].f), + "Appended second sample not as expected. Wanted: stale NaN Got: %x", math.Float64bits(appender.resultFloats[6].f)) } func TestScrapeLoopCache(t *testing.T) { @@ -1342,7 +1342,7 @@ func TestScrapeLoopCache(t *testing.T) { // 1 successfully scraped sample, 1 stale marker after first fail, 5 report samples for // each scrape successful or not. - require.Equal(t, 26, len(appender.result), "Appended samples not as expected:\n%s", appender) + require.Equal(t, 26, len(appender.resultFloats), "Appended samples not as expected:\n%s", appender) } func TestScrapeLoopCacheMemoryExhaustionProtection(t *testing.T) { @@ -1501,11 +1501,11 @@ func TestScrapeLoopAppend(t *testing.T) { require.NoError(t, err) require.NoError(t, slApp.Commit()) - expected := []sample{ + expected := []floatSample{ { metric: test.expLset, t: timestamp.FromTime(now), - v: test.expValue, + f: test.expValue, }, } @@ -1513,11 +1513,11 @@ func TestScrapeLoopAppend(t *testing.T) { // DeepEqual will report NaNs as being different, // so replace it with the expected one. if test.expValue == float64(value.NormalNaN) { - app.result[0].v = expected[0].v + app.resultFloats[0].f = expected[0].f } t.Logf("Test:%s", test.title) - require.Equal(t, expected, app.result) + require.Equal(t, expected, app.resultFloats) } } @@ -1587,13 +1587,13 @@ func TestScrapeLoopAppendForConflictingPrefixedLabels(t *testing.T) { require.NoError(t, slApp.Commit()) - require.Equal(t, []sample{ + require.Equal(t, []floatSample{ { metric: labels.FromStrings(tc.expected...), t: timestamp.FromTime(time.Date(2000, 1, 1, 1, 0, 0, 0, time.UTC)), - v: 0, + f: 0, }, - }, app.result) + }, app.resultFloats) }) } } @@ -1641,15 +1641,15 @@ func TestScrapeLoopAppendCacheEntryButErrNotFound(t *testing.T) { require.NoError(t, err) require.NoError(t, slApp.Commit()) - expected := []sample{ + expected := []floatSample{ { metric: lset, t: timestamp.FromTime(now), - v: expValue, + f: expValue, }, } - require.Equal(t, expected, app.result) + require.Equal(t, expected, app.resultFloats) } func TestScrapeLoopAppendSampleLimit(t *testing.T) { @@ -1709,14 +1709,14 @@ func TestScrapeLoopAppendSampleLimit(t *testing.T) { require.Equal(t, 1.0, change, "Unexpected change of sample limit metric: %f", change) // And verify that we got the samples that fit under the limit. - want := []sample{ + want := []floatSample{ { metric: labels.FromStrings(model.MetricNameLabel, "metric_a"), t: timestamp.FromTime(now), - v: 1, + f: 1, }, } - require.Equal(t, want, resApp.rolledbackResult, "Appended samples not as expected:\n%s", appender) + require.Equal(t, want, resApp.rolledbackFloats, "Appended samples not as expected:\n%s", appender) now = time.Now() slApp = sl.appender(context.Background()) @@ -1869,19 +1869,19 @@ func TestScrapeLoop_ChangingMetricString(t *testing.T) { require.NoError(t, slApp.Commit()) // DeepEqual will report NaNs as being different, so replace with a different value. - want := []sample{ + want := []floatSample{ { metric: labels.FromStrings("__name__", "metric_a", "a", "1", "b", "1"), t: timestamp.FromTime(now), - v: 1, + f: 1, }, { metric: labels.FromStrings("__name__", "metric_a", "a", "1", "b", "1"), t: timestamp.FromTime(now.Add(time.Minute)), - v: 2, + f: 2, }, } - require.Equal(t, want, capp.result, "Appended samples not as expected:\n%s", appender) + require.Equal(t, want, capp.resultFloats, "Appended samples not as expected:\n%s", appender) } func TestScrapeLoopAppendStaleness(t *testing.T) { @@ -1917,24 +1917,24 @@ func TestScrapeLoopAppendStaleness(t *testing.T) { require.NoError(t, err) require.NoError(t, slApp.Commit()) - ingestedNaN := math.Float64bits(app.result[1].v) + ingestedNaN := math.Float64bits(app.resultFloats[1].f) require.Equal(t, value.StaleNaN, ingestedNaN, "Appended stale sample wasn't as expected") // DeepEqual will report NaNs as being different, so replace with a different value. - app.result[1].v = 42 - want := []sample{ + app.resultFloats[1].f = 42 + want := []floatSample{ { metric: labels.FromStrings(model.MetricNameLabel, "metric_a"), t: timestamp.FromTime(now), - v: 1, + f: 1, }, { metric: labels.FromStrings(model.MetricNameLabel, "metric_a"), t: timestamp.FromTime(now.Add(time.Second)), - v: 42, + f: 42, }, } - require.Equal(t, want, app.result, "Appended samples not as expected:\n%s", appender) + require.Equal(t, want, app.resultFloats, "Appended samples not as expected:\n%s", appender) } func TestScrapeLoopAppendNoStalenessIfTimestamp(t *testing.T) { @@ -1969,14 +1969,14 @@ func TestScrapeLoopAppendNoStalenessIfTimestamp(t *testing.T) { require.NoError(t, err) require.NoError(t, slApp.Commit()) - want := []sample{ + want := []floatSample{ { metric: labels.FromStrings(model.MetricNameLabel, "metric_a"), t: 1000, - v: 1, + f: 1, }, } - require.Equal(t, want, app.result, "Appended samples not as expected:\n%s", appender) + require.Equal(t, want, app.resultFloats, "Appended samples not as expected:\n%s", appender) } func TestScrapeLoopAppendExemplar(t *testing.T) { @@ -1985,7 +1985,7 @@ func TestScrapeLoopAppendExemplar(t *testing.T) { scrapeText string contentType string discoveryLabels []string - floats []sample + floats []floatSample histograms []histogramSample exemplars []exemplar.Exemplar }{ @@ -1994,9 +1994,9 @@ func TestScrapeLoopAppendExemplar(t *testing.T) { scrapeText: "metric_total{n=\"1\"} 0\n# EOF", contentType: "application/openmetrics-text", discoveryLabels: []string{"n", "2"}, - floats: []sample{{ + floats: []floatSample{{ metric: labels.FromStrings("__name__", "metric_total", "exported_n", "1", "n", "2"), - v: 0, + f: 0, }}, }, { @@ -2004,9 +2004,9 @@ func TestScrapeLoopAppendExemplar(t *testing.T) { scrapeText: "metric_total{n=\"1\"} 0 # {a=\"abc\"} 1.0\n# EOF", contentType: "application/openmetrics-text", discoveryLabels: []string{"n", "2"}, - floats: []sample{{ + floats: []floatSample{{ metric: labels.FromStrings("__name__", "metric_total", "exported_n", "1", "n", "2"), - v: 0, + f: 0, }}, exemplars: []exemplar.Exemplar{ {Labels: labels.FromStrings("a", "abc"), Value: 1}, @@ -2017,9 +2017,9 @@ func TestScrapeLoopAppendExemplar(t *testing.T) { scrapeText: "metric_total{n=\"1\"} 0 # {a=\"abc\"} 1.0 10000\n# EOF", contentType: "application/openmetrics-text", discoveryLabels: []string{"n", "2"}, - floats: []sample{{ + floats: []floatSample{{ metric: labels.FromStrings("__name__", "metric_total", "exported_n", "1", "n", "2"), - v: 0, + f: 0, }}, exemplars: []exemplar.Exemplar{ {Labels: labels.FromStrings("a", "abc"), Value: 1, Ts: 10000000, HasTs: true}, @@ -2031,12 +2031,12 @@ func TestScrapeLoopAppendExemplar(t *testing.T) { metric_total{n="2"} 2 # {t="2"} 2.0 20000 # EOF`, contentType: "application/openmetrics-text", - floats: []sample{{ + floats: []floatSample{{ metric: labels.FromStrings("__name__", "metric_total", "n", "1"), - v: 1, + f: 1, }, { metric: labels.FromStrings("__name__", "metric_total", "n", "2"), - v: 2, + f: 2, }}, exemplars: []exemplar.Exemplar{ {Labels: labels.FromStrings("t", "1"), Value: 1, Ts: 10000000, HasTs: true}, @@ -2208,7 +2208,7 @@ metric: < _, _, _, err := sl.append(app, buf.Bytes(), test.contentType, now) require.NoError(t, err) require.NoError(t, app.Commit()) - require.Equal(t, test.floats, app.result) + require.Equal(t, test.floats, app.resultFloats) require.Equal(t, test.histograms, app.resultHistograms) require.Equal(t, test.exemplars, app.resultExemplars) }) @@ -2219,12 +2219,12 @@ func TestScrapeLoopAppendExemplarSeries(t *testing.T) { scrapeText := []string{`metric_total{n="1"} 1 # {t="1"} 1.0 10000 # EOF`, `metric_total{n="1"} 2 # {t="2"} 2.0 20000 # EOF`} - samples := []sample{{ + samples := []floatSample{{ metric: labels.FromStrings("__name__", "metric_total", "n", "1"), - v: 1, + f: 1, }, { metric: labels.FromStrings("__name__", "metric_total", "n", "1"), - v: 2, + f: 2, }} exemplars := []exemplar.Exemplar{ {Labels: labels.FromStrings("t", "1"), Value: 1, Ts: 10000000, HasTs: true}, @@ -2280,7 +2280,7 @@ func TestScrapeLoopAppendExemplarSeries(t *testing.T) { require.NoError(t, app.Commit()) } - require.Equal(t, samples, app.result) + require.Equal(t, samples, app.resultFloats) require.Equal(t, exemplars, app.resultExemplars) } @@ -2318,7 +2318,7 @@ func TestScrapeLoopRunReportsTargetDownOnScrapeError(t *testing.T) { } sl.run(nil) - require.Equal(t, 0.0, appender.result[0].v, "bad 'up' value") + require.Equal(t, 0.0, appender.resultFloats[0].f, "bad 'up' value") } func TestScrapeLoopRunReportsTargetDownOnInvalidUTF8(t *testing.T) { @@ -2356,7 +2356,7 @@ func TestScrapeLoopRunReportsTargetDownOnInvalidUTF8(t *testing.T) { } sl.run(nil) - require.Equal(t, 0.0, appender.result[0].v, "bad 'up' value") + require.Equal(t, 0.0, appender.resultFloats[0].f, "bad 'up' value") } type errorAppender struct { @@ -2405,14 +2405,14 @@ func TestScrapeLoopAppendGracefullyIfAmendOrOutOfOrderOrOutOfBounds(t *testing.T require.NoError(t, err) require.NoError(t, slApp.Commit()) - want := []sample{ + want := []floatSample{ { metric: labels.FromStrings(model.MetricNameLabel, "normal"), t: timestamp.FromTime(now), - v: 1, + f: 1, }, } - require.Equal(t, want, app.result, "Appended samples not as expected:\n%s", appender) + require.Equal(t, want, app.resultFloats, "Appended samples not as expected:\n%s", appender) require.Equal(t, 4, total) require.Equal(t, 4, added) require.Equal(t, 1, seriesAdded) @@ -2724,14 +2724,14 @@ func TestScrapeLoop_RespectTimestamps(t *testing.T) { require.NoError(t, err) require.NoError(t, slApp.Commit()) - want := []sample{ + want := []floatSample{ { metric: labels.FromStrings("__name__", "metric_a", "a", "1", "b", "1"), t: 0, - v: 1, + f: 1, }, } - require.Equal(t, want, capp.result, "Appended samples not as expected:\n%s", appender) + require.Equal(t, want, capp.resultFloats, "Appended samples not as expected:\n%s", appender) } func TestScrapeLoop_DiscardTimestamps(t *testing.T) { @@ -2766,14 +2766,14 @@ func TestScrapeLoop_DiscardTimestamps(t *testing.T) { require.NoError(t, err) require.NoError(t, slApp.Commit()) - want := []sample{ + want := []floatSample{ { metric: labels.FromStrings("__name__", "metric_a", "a", "1", "b", "1"), t: timestamp.FromTime(now), - v: 1, + f: 1, }, } - require.Equal(t, want, capp.result, "Appended samples not as expected:\n%s", appender) + require.Equal(t, want, capp.resultFloats, "Appended samples not as expected:\n%s", appender) } func TestScrapeLoopDiscardDuplicateLabels(t *testing.T) {