lib/promscrape: fix tests after the commit 658a8742ac

The original commit copies `__address__` label to `instance` label when generating per-target labels as Prometheus does.

See https://www.robustperception.io/life-of-a-label for details.

Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/453
This commit is contained in:
Aliaksandr Valialkin 2020-05-03 16:41:33 +03:00
parent 317688f144
commit 1f0e8fdc0d
7 changed files with 132 additions and 38 deletions

View File

@ -45,12 +45,10 @@ func ApplyRelabelConfigs(labels []prompbmarshal.Label, labelsOffset int, prcs []
} }
labels = tmp labels = tmp
} }
labels = removeEmptyLabels(labels, labelsOffset)
if isFinalize { if isFinalize {
labels = FinalizeLabels(labels[:labelsOffset], labels[labelsOffset:]) labels = FinalizeLabels(labels[:labelsOffset], labels[labelsOffset:])
} }
// remove empty empty labels after finalize, or we can't tell if the label value
// is null character or not set when finalize labels
labels = removeEmptyLabels(labels, labelsOffset)
SortLabels(labels[labelsOffset:]) SortLabels(labels[labelsOffset:])
return labels return labels
} }
@ -92,29 +90,15 @@ func RemoveMetaLabels(dst, src []prompbmarshal.Label) []prompbmarshal.Label {
return dst return dst
} }
// FinalizeLabels finalizes labels according to relabel_config rules. // FinalizeLabels removes labels with "__" in the beginning (except of "__name__").
//
// It renames `__address__` to `instance` and removes labels with "__" in the beginning.
//
// See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config
func FinalizeLabels(dst, src []prompbmarshal.Label) []prompbmarshal.Label { func FinalizeLabels(dst, src []prompbmarshal.Label) []prompbmarshal.Label {
for i := range src { for i := range src {
label := &src[i] label := &src[i]
name := label.Name name := label.Name
if !strings.HasPrefix(name, "__") || name == "__name__" { if strings.HasPrefix(name, "__") && name != "__name__" {
dst = append(dst, *label)
continue continue
} }
if name == "__address__" { dst = append(dst, *label)
if GetLabelByName(src, "instance") != nil {
// The `instance` label is already set. Skip `__address__` label.
continue
}
// Rename `__address__` label to `instance`.
labelCopy := *label
labelCopy.Name = "instance"
dst = append(dst, labelCopy)
}
} }
return dst return dst
} }

View File

@ -16,7 +16,7 @@ func TestApplyRelabelConfigs(t *testing.T) {
t.Fatalf("unexpected result; got\n%v\nwant\n%v", result, resultExpected) t.Fatalf("unexpected result; got\n%v\nwant\n%v", result, resultExpected)
} }
} }
t.Run("empty_replabel_configs", func(t *testing.T) { t.Run("empty_relabel_configs", func(t *testing.T) {
f(nil, nil, false, nil) f(nil, nil, false, nil)
f(nil, nil, true, nil) f(nil, nil, true, nil)
f(nil, []prompbmarshal.Label{ f(nil, []prompbmarshal.Label{
@ -238,7 +238,7 @@ func TestApplyRelabelConfigs(t *testing.T) {
Value: "yyy", Value: "yyy",
}, },
{ {
Name: "__address__", Name: "instance",
Value: "a.bc", Value: "a.bc",
}, },
}, true, []prompbmarshal.Label{ }, true, []prompbmarshal.Label{
@ -591,7 +591,7 @@ func TestFinalizeLabels(t *testing.T) {
Value: "ass", Value: "ass",
}, },
{ {
Name: "__address__", Name: "instance",
Value: "foo.com", Value: "foo.com",
}, },
}, []prompbmarshal.Label{ }, []prompbmarshal.Label{

View File

@ -430,16 +430,7 @@ func appendScrapeWork(dst []ScrapeWork, swc *scrapeWorkConfig, target string, ex
// Drop target with '/' // Drop target with '/'
return dst, nil return dst, nil
} }
instanceRelabeled := promrelabel.GetLabelValueByName(labels, "instance") addressRelabeled = addMissingPort(schemeRelabeled, addressRelabeled)
if instanceRelabeled == "" {
// After relabeling, the instance label is set to the value of __address__ by default
// if it was not set during relabeling.
labels = append(labels, prompbmarshal.Label{
Name: "instance",
Value: addressRelabeled,
})
}
metricsPathRelabeled := promrelabel.GetLabelValueByName(labels, "__metrics_path__") metricsPathRelabeled := promrelabel.GetLabelValueByName(labels, "__metrics_path__")
if metricsPathRelabeled == "" { if metricsPathRelabeled == "" {
metricsPathRelabeled = "/metrics" metricsPathRelabeled = "/metrics"
@ -455,6 +446,14 @@ func appendScrapeWork(dst []ScrapeWork, swc *scrapeWorkConfig, target string, ex
return dst, fmt.Errorf("invalid url %q for scheme=%q (%q), target=%q (%q), metrics_path=%q (%q) for `job_name` %q: %s", return dst, fmt.Errorf("invalid url %q for scheme=%q (%q), target=%q (%q), metrics_path=%q (%q) for `job_name` %q: %s",
scrapeURL, swc.scheme, schemeRelabeled, target, addressRelabeled, swc.metricsPath, metricsPathRelabeled, swc.jobName, err) scrapeURL, swc.scheme, schemeRelabeled, target, addressRelabeled, swc.metricsPath, metricsPathRelabeled, swc.jobName, err)
} }
// Set missing "instance" label according to https://www.robustperception.io/life-of-a-label
if promrelabel.GetLabelByName(labels, "instance") == nil {
labels = append(labels, prompbmarshal.Label{
Name: "instance",
Value: addressRelabeled,
})
promrelabel.SortLabels(labels)
}
dst = append(dst, ScrapeWork{ dst = append(dst, ScrapeWork{
ID: atomic.AddUint64(&nextScrapeWorkID, 1), ID: atomic.AddUint64(&nextScrapeWorkID, 1),
ScrapeURL: scrapeURL, ScrapeURL: scrapeURL,
@ -498,7 +497,7 @@ func mergeLabels(job, scheme, target, metricsPath string, extraLabels, externalL
m[k] = v m[k] = v
} }
m["job"] = job m["job"] = job
m["__address__"] = addMissingPort(scheme, target) m["__address__"] = target
m["__scheme__"] = scheme m["__scheme__"] = scheme
m["__metrics_path__"] = metricsPath m["__metrics_path__"] = metricsPath
for k, args := range params { for k, args := range params {

View File

@ -438,6 +438,10 @@ scrape_configs:
Name: "__vm_filepath", Name: "__vm_filepath",
Value: "", Value: "",
}, },
{
Name: "instance",
Value: "host1:80",
},
{ {
Name: "job", Name: "job",
Value: "foo", Value: "foo",
@ -472,6 +476,10 @@ scrape_configs:
Name: "__vm_filepath", Name: "__vm_filepath",
Value: "", Value: "",
}, },
{
Name: "instance",
Value: "host2:80",
},
{ {
Name: "job", Name: "job",
Value: "foo", Value: "foo",
@ -506,6 +514,10 @@ scrape_configs:
Name: "__vm_filepath", Name: "__vm_filepath",
Value: "", Value: "",
}, },
{
Name: "instance",
Value: "localhost:9090",
},
{ {
Name: "job", Name: "job",
Value: "foo", Value: "foo",
@ -558,6 +570,10 @@ scrape_configs:
Name: "__scheme__", Name: "__scheme__",
Value: "http", Value: "http",
}, },
{
Name: "instance",
Value: "foo.bar:1234",
},
{ {
Name: "job", Name: "job",
Value: "foo", Value: "foo",
@ -599,6 +615,10 @@ scrape_configs:
Name: "datacenter", Name: "datacenter",
Value: "foobar", Value: "foobar",
}, },
{
Name: "instance",
Value: "foo.bar:1234",
},
{ {
Name: "job", Name: "job",
Value: "foo", Value: "foo",
@ -664,6 +684,10 @@ scrape_configs:
Name: "__scheme__", Name: "__scheme__",
Value: "https", Value: "https",
}, },
{
Name: "instance",
Value: "foo.bar:443",
},
{ {
Name: "job", Name: "job",
Value: "foo", Value: "foo",
@ -700,6 +724,10 @@ scrape_configs:
Name: "__scheme__", Name: "__scheme__",
Value: "https", Value: "https",
}, },
{
Name: "instance",
Value: "aaa:443",
},
{ {
Name: "job", Name: "job",
Value: "foo", Value: "foo",
@ -732,6 +760,10 @@ scrape_configs:
Name: "__scheme__", Name: "__scheme__",
Value: "http", Value: "http",
}, },
{
Name: "instance",
Value: "1.2.3.4:80",
},
{ {
Name: "job", Name: "job",
Value: "qwer", Value: "qwer",
@ -805,6 +837,10 @@ scrape_configs:
Name: "hash", Name: "hash",
Value: "82", Value: "82",
}, },
{
Name: "instance",
Value: "foo.bar:1234",
},
{ {
Name: "prefix:url", Name: "prefix:url",
Value: "http://foo.bar:1234/metrics", Value: "http://foo.bar:1234/metrics",
@ -904,6 +940,10 @@ scrape_configs:
Name: "__address__", Name: "__address__",
Value: "foo.bar:1234", Value: "foo.bar:1234",
}, },
{
Name: "instance",
Value: "foo.bar:1234",
},
{ {
Name: "job", Name: "job",
Value: "3", Value: "3",
@ -938,6 +978,10 @@ scrape_configs:
Name: "__scheme__", Name: "__scheme__",
Value: "http", Value: "http",
}, },
{
Name: "instance",
Value: "foo.bar:1234",
},
{ {
Name: "job", Name: "job",
Value: "foo", Value: "foo",
@ -982,6 +1026,10 @@ scrape_configs:
Name: "__scheme__", Name: "__scheme__",
Value: "http", Value: "http",
}, },
{
Name: "instance",
Value: "foo.bar:1234",
},
{ {
Name: "job", Name: "job",
Value: "foo", Value: "foo",
@ -1016,6 +1064,10 @@ scrape_configs:
Name: "__scheme__", Name: "__scheme__",
Value: "http", Value: "http",
}, },
{
Name: "instance",
Value: "foo.bar:1234",
},
{ {
Name: "job", Name: "job",
Value: "foo", Value: "foo",
@ -1056,6 +1108,10 @@ scrape_configs:
Name: "__scheme__", Name: "__scheme__",
Value: "http", Value: "http",
}, },
{
Name: "instance",
Value: "foo.bar:1234",
},
{ {
Name: "job", Name: "job",
Value: "foo", Value: "foo",
@ -1111,6 +1167,10 @@ scrape_configs:
Name: "foo", Name: "foo",
Value: "bar", Value: "bar",
}, },
{
Name: "instance",
Value: "pp:80",
},
{ {
Name: "job", Name: "job",
Value: "yyy", Value: "yyy",

View File

@ -99,7 +99,7 @@ func TestScrapeWorkScrapeInternalSuccess(t *testing.T) {
scrape_samples_post_metric_relabeling 0 123 scrape_samples_post_metric_relabeling 0 123
`) `)
f(` f(`
foo{bar="baz"} 34.45 3 foo{bar="baz",empty_label=""} 34.45 3
abc -2 abc -2
`, &ScrapeWork{}, ` `, &ScrapeWork{}, `
foo{bar="baz"} 34.45 123 foo{bar="baz"} 34.45 123
@ -147,6 +147,53 @@ func TestScrapeWorkScrapeInternalSuccess(t *testing.T) {
scrape_duration_seconds{job="override"} 0 123 scrape_duration_seconds{job="override"} 0 123
scrape_samples_post_metric_relabeling{job="override"} 2 123 scrape_samples_post_metric_relabeling{job="override"} 2 123
`) `)
// Empty instance override. See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/453
f(`
no_instance{instance="",job="some_job",label="val1",test=""} 5555
test_with_instance{instance="some_instance",job="some_job",label="val2",test=""} 1555
`, &ScrapeWork{
HonorLabels: true,
Labels: []prompbmarshal.Label{
{
Name: "instance",
Value: "foobar",
},
{
Name: "job",
Value: "xxx",
},
},
}, `
no_instance{job="some_job",label="val1"} 5555 123
test_with_instance{instance="some_instance",job="some_job",label="val2"} 1555 123
up{instance="foobar",job="xxx"} 1 123
scrape_samples_scraped{instance="foobar",job="xxx"} 2 123
scrape_duration_seconds{instance="foobar",job="xxx"} 0 123
scrape_samples_post_metric_relabeling{instance="foobar",job="xxx"} 2 123
`)
f(`
no_instance{instance="",job="some_job",label="val1",test=""} 5555
test_with_instance{instance="some_instance",job="some_job",label="val2",test=""} 1555
`, &ScrapeWork{
HonorLabels: false,
Labels: []prompbmarshal.Label{
{
Name: "instance",
Value: "foobar",
},
{
Name: "job",
Value: "xxx",
},
},
}, `
no_instance{exported_job="some_job",instance="foobar",job="xxx",label="val1"} 5555 123
test_with_instance{exported_instance="some_instance",exported_job="some_job",instance="foobar",job="xxx",label="val2"} 1555 123
up{instance="foobar",job="xxx"} 1 123
scrape_samples_scraped{instance="foobar",job="xxx"} 2 123
scrape_duration_seconds{instance="foobar",job="xxx"} 0 123
scrape_samples_post_metric_relabeling{instance="foobar",job="xxx"} 2 123
`)
f(` f(`
foo{job="orig",bar="baz"} 34.45 foo{job="orig",bar="baz"} 34.45
bar{job="aa",a="b",job="bb"} -3e4 2345 bar{job="aa",a="b",job="bb"} -3e4 2345
@ -205,7 +252,7 @@ func TestScrapeWorkScrapeInternalSuccess(t *testing.T) {
`) `)
f(` f(`
foo{bar="baz"} 34.44 foo{bar="baz"} 34.44
bar{a="b",c="d"} -3e4 bar{a="b",c="d",} -3e4
dropme{foo="bar"} 334 dropme{foo="bar"} 334
dropme{xxx="yy",ss="dsf"} 843 dropme{xxx="yy",ss="dsf"} 843
`, &ScrapeWork{ `, &ScrapeWork{
@ -216,7 +263,7 @@ func TestScrapeWorkScrapeInternalSuccess(t *testing.T) {
Value: "xx", Value: "xx",
}, },
{ {
Name: "__address__", Name: "instance",
Value: "foo.com", Value: "foo.com",
}, },
}, },

View File

@ -230,8 +230,8 @@ func unmarshalTags(dst []Tag, s string, noEscapes bool) (string, []Tag, error) {
} }
s = s[n+1:] s = s[n+1:]
} }
// keep null character label value
if len(key) > 0 { if len(key) > 0 {
// Allow empty values (len(value)==0) - see https://github.com/VictoriaMetrics/VictoriaMetrics/issues/453
if cap(dst) > len(dst) { if cap(dst) > len(dst) {
dst = dst[:len(dst)+1] dst = dst[:len(dst)+1]
} else { } else {

View File

@ -221,6 +221,10 @@ func TestRowsUnmarshalSuccess(t *testing.T) {
Key: "bar", Key: "bar",
Value: "baz", Value: "baz",
}, },
{
Key: "aa",
Value: "",
},
{ {
Key: "x", Key: "x",
Value: "y", Value: "y",