web/api: compute relabel_steps in single pass

Signed-off-by: 1seal <security@1seal.org>
This commit is contained in:
1seal 2026-01-29 11:59:35 +00:00
parent 36ea75d203
commit 79b553499a
2 changed files with 64 additions and 8 deletions

View file

@ -1346,13 +1346,19 @@ func (api *API) targetRelabelSteps(r *http.Request) apiFuncResult {
rules := scrapeConfig.RelabelConfigs
steps := make([]RelabelStep, len(rules))
lb := labels.NewBuilder(lbls)
keep := true
for i, rule := range rules {
outLabels, keep := relabel.Process(lbls, rules[:i+1]...)
steps[i] = RelabelStep{
Rule: rule,
Output: outLabels,
Keep: keep,
if keep {
keep = relabel.ProcessBuilder(lb, rule)
}
outLabels := labels.EmptyLabels()
if keep {
outLabels = lb.Labels()
}
steps[i] = RelabelStep{Rule: rule, Output: outLabels, Keep: keep}
}
return apiFuncResult{&RelabelStepsResponse{Steps: steps}, nil, nil, nil}

View file

@ -166,8 +166,8 @@ func (t testTargetRetriever) TargetsDroppedCounts() map[string]int {
return r
}
func (testTargetRetriever) ScrapePoolConfig(_ string) (*config.ScrapeConfig, error) {
return &config.ScrapeConfig{
func (testTargetRetriever) ScrapePoolConfig(pool string) (*config.ScrapeConfig, error) {
cfg := &config.ScrapeConfig{
RelabelConfigs: []*relabel.Config{
{
Action: relabel.Replace,
@ -182,7 +182,16 @@ func (testTargetRetriever) ScrapePoolConfig(_ string) (*config.ScrapeConfig, err
Regex: relabel.MustNewRegexp(`example\.com:.*`),
},
},
}, nil
}
if pool == "testpool3" {
cfg.RelabelConfigs = append(cfg.RelabelConfigs, &relabel.Config{
Action: relabel.Replace,
TargetLabel: "job",
Regex: relabel.MustNewRegexp(".*"),
Replacement: "should_not_apply",
})
}
return cfg, nil
}
func (t *testTargetRetriever) SetMetadataStoreForTargets(identifier string, metadata scrape.MetricMetadataStore) error {
@ -1937,6 +1946,47 @@ func testEndpoints(t *testing.T, api *API, tr *testTargetRetriever, testLabelAPI
},
},
},
{
endpoint: api.targetRelabelSteps,
query: url.Values{"scrapePool": []string{"testpool3"}, "labels": []string{`{"job":"test","__address__":"localhost:9090"}`}},
response: &RelabelStepsResponse{
Steps: []RelabelStep{
{
Rule: &relabel.Config{
Action: relabel.Replace,
Replacement: "example.com:443",
TargetLabel: "__address__",
Regex: relabel.MustNewRegexp(""),
NameValidationScheme: model.LegacyValidation,
},
Output: labels.FromMap(map[string]string{
"job": "test",
"__address__": "example.com:443",
}),
Keep: true,
},
{
Rule: &relabel.Config{
Action: relabel.Drop,
SourceLabels: []model.LabelName{"__address__"},
Regex: relabel.MustNewRegexp(`example\.com:.*`),
},
Output: labels.EmptyLabels(),
Keep: false,
},
{
Rule: &relabel.Config{
Action: relabel.Replace,
TargetLabel: "job",
Regex: relabel.MustNewRegexp(".*"),
Replacement: "should_not_apply",
},
Output: labels.EmptyLabels(),
Keep: false,
},
},
},
},
// With a matching metric.
{
endpoint: api.targetMetadata,