From 9ba13de220f7b15e6b0554d7a045e4225e366e09 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Sun, 16 Apr 2023 14:15:13 +0200 Subject: [PATCH] scraping: pass a Builder to get Target labels This saves memory allocations from making a new Builder every time. Signed-off-by: Bryan Boreham --- scrape/target.go | 4 ++-- scrape/target_test.go | 3 ++- web/api/v1/api.go | 11 +++++++---- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/scrape/target.go b/scrape/target.go index c9287f818..ad4b4f685 100644 --- a/scrape/target.go +++ b/scrape/target.go @@ -169,8 +169,8 @@ func (t *Target) offset(interval time.Duration, offsetSeed uint64) time.Duration } // Labels returns a copy of the set of all public labels of the target. -func (t *Target) Labels() labels.Labels { - b := labels.NewScratchBuilder(t.labels.Len()) +func (t *Target) Labels(b *labels.ScratchBuilder) labels.Labels { + b.Reset() t.labels.Range(func(l labels.Label) { if !strings.HasPrefix(l.Name, model.ReservedLabelPrefix) { b.Add(l.Name, l.Value) diff --git a/scrape/target_test.go b/scrape/target_test.go index 6e87ce71d..413fbc1b8 100644 --- a/scrape/target_test.go +++ b/scrape/target_test.go @@ -42,7 +42,8 @@ const ( func TestTargetLabels(t *testing.T) { target := newTestTarget("example.com:80", 0, labels.FromStrings("job", "some_job", "foo", "bar")) want := labels.FromStrings(model.JobLabel, "some_job", "foo", "bar") - got := target.Labels() + b := labels.NewScratchBuilder(0) + got := target.Labels(&b) require.Equal(t, want, got) i := 0 target.LabelsRange(func(l labels.Label) { diff --git a/web/api/v1/api.go b/web/api/v1/api.go index 0c02293bf..fcb55026e 100644 --- a/web/api/v1/api.go +++ b/web/api/v1/api.go @@ -1009,6 +1009,7 @@ func (api *API) targets(r *http.Request) apiFuncResult { targetsActive := api.targetRetriever(r.Context()).TargetsActive() activeKeys, numTargets := sortKeys(targetsActive) res.ActiveTargets = make([]*Target, 0, numTargets) + builder := labels.NewScratchBuilder(0) for _, key := range activeKeys { if scrapePool != "" && key != scrapePool { @@ -1025,7 +1026,7 @@ func (api *API) targets(r *http.Request) apiFuncResult { res.ActiveTargets = append(res.ActiveTargets, &Target{ DiscoveredLabels: target.DiscoveredLabels(), - Labels: target.Labels(), + Labels: target.Labels(&builder), ScrapePool: key, ScrapeURL: target.URL().String(), GlobalURL: globalURL.String(), @@ -1101,6 +1102,7 @@ func (api *API) targetMetadata(r *http.Request) apiFuncResult { } } + builder := labels.NewScratchBuilder(0) metric := r.FormValue("metric") res := []metricMetadata{} for _, tt := range api.targetRetriever(r.Context()).TargetsActive() { @@ -1108,15 +1110,16 @@ func (api *API) targetMetadata(r *http.Request) apiFuncResult { if limit >= 0 && len(res) >= limit { break } + targetLabels := t.Labels(&builder) // Filter targets that don't satisfy the label matchers. - if matchTarget != "" && !matchLabels(t.Labels(), matchers) { + if matchTarget != "" && !matchLabels(targetLabels, matchers) { continue } // If no metric is specified, get the full list for the target. if metric == "" { for _, md := range t.ListMetadata() { res = append(res, metricMetadata{ - Target: t.Labels(), + Target: targetLabels, Metric: md.Metric, Type: md.Type, Help: md.Help, @@ -1128,7 +1131,7 @@ func (api *API) targetMetadata(r *http.Request) apiFuncResult { // Get metadata for the specified metric. if md, ok := t.GetMetadata(metric); ok { res = append(res, metricMetadata{ - Target: t.Labels(), + Target: targetLabels, Type: md.Type, Help: md.Help, Unit: md.Unit,