Fix the duplicated results issue from /api/v1/series (#7862)

* Fix the duplicated results issue from /api/v1/series

Signed-off-by: Luke Chen <showuon@gmail.com>
This commit is contained in:
showuon 2020-08-29 07:21:39 +08:00 committed by GitHub
parent 085352ba97
commit dfdc358a5b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 9 deletions

View file

@ -331,7 +331,7 @@ func (c *genericMergeSeriesSet) Next() bool {
// If, for the current label set, all the next series sets come from
// failed remote storage sources, we want to keep trying with the next label set.
for {
// Firstly advance all the current series sets. If any of them have run out
// Firstly advance all the current series sets. If any of them have run out,
// we can drop them, otherwise they should be inserted back into the heap.
for _, set := range c.currentSets {
if set.Next() {

View file

@ -603,7 +603,8 @@ func (api *API) series(r *http.Request) (result apiFuncResult) {
var sets []storage.SeriesSet
for _, mset := range matcherSets {
s := q.Select(false, nil, mset...)
// We need to sort this select results to merge (deduplicate) the series sets later.
s := q.Select(true, nil, mset...)
sets = append(sets, s)
}

View file

@ -303,6 +303,11 @@ func TestEndpoints(t *testing.T) {
test_metric1{foo="bar"} 0+100x100
test_metric1{foo="boo"} 1+0x100
test_metric2{foo="boo"} 1+0x100
test_metric3{foo="bar", dup="1"} 1+0x100
test_metric3{foo="boo", dup="1"} 1+0x100
test_metric4{foo="bar", dup="1"} 1+0x100
test_metric4{foo="boo", dup="1"} 1+0x100
test_metric4{foo="boo"} 1+0x100
`)
testutil.Ok(t, err)
defer suite.Close()
@ -737,6 +742,18 @@ func testEndpoints(t *testing.T, api *API, tr *testTargetRetriever, testLabelAPI
labels.FromStrings("__name__", "test_metric1", "foo", "boo"),
},
},
// Try to overlap the selected series set as much as possible to test the result de-duplication works well.
{
endpoint: api.series,
query: url.Values{
"match[]": []string{`test_metric4{foo=~".+o$"}`, `test_metric4{dup=~"^1"}`},
},
response: []labels.Labels{
labels.FromStrings("__name__", "test_metric4", "dup", "1", "foo", "bar"),
labels.FromStrings("__name__", "test_metric4", "dup", "1", "foo", "boo"),
labels.FromStrings("__name__", "test_metric4", "foo", "boo"),
},
},
{
endpoint: api.series,
query: url.Values{
@ -1449,6 +1466,8 @@ func testEndpoints(t *testing.T, api *API, tr *testTargetRetriever, testLabelAPI
response: []string{
"test_metric1",
"test_metric2",
"test_metric3",
"test_metric4",
},
},
{
@ -1597,7 +1616,7 @@ func testEndpoints(t *testing.T, api *API, tr *testTargetRetriever, testLabelAPI
// Label names.
{
endpoint: api.labelNames,
response: []string{"__name__", "foo"},
response: []string{"__name__", "dup", "foo"},
},
// Start and end before Label names starts.
{
@ -1615,7 +1634,7 @@ func testEndpoints(t *testing.T, api *API, tr *testTargetRetriever, testLabelAPI
"start": []string{"1"},
"end": []string{"100"},
},
response: []string{"__name__", "foo"},
response: []string{"__name__", "dup", "foo"},
},
// Start before Label names, end within Label names.
{
@ -1624,7 +1643,7 @@ func testEndpoints(t *testing.T, api *API, tr *testTargetRetriever, testLabelAPI
"start": []string{"-1"},
"end": []string{"10"},
},
response: []string{"__name__", "foo"},
response: []string{"__name__", "dup", "foo"},
},
// Start before Label names starts, end after Label names ends.
@ -1634,7 +1653,7 @@ func testEndpoints(t *testing.T, api *API, tr *testTargetRetriever, testLabelAPI
"start": []string{"-1"},
"end": []string{"100000"},
},
response: []string{"__name__", "foo"},
response: []string{"__name__", "dup", "foo"},
},
// Start with bad data for Label names, end within Label names.
{
@ -1652,7 +1671,7 @@ func testEndpoints(t *testing.T, api *API, tr *testTargetRetriever, testLabelAPI
"start": []string{"1"},
"end": []string{"1000000006"},
},
response: []string{"__name__", "foo"},
response: []string{"__name__", "dup", "foo"},
},
// Start and end after Label names ends.
{
@ -1669,7 +1688,7 @@ func testEndpoints(t *testing.T, api *API, tr *testTargetRetriever, testLabelAPI
query: url.Values{
"start": []string{"4"},
},
response: []string{"__name__", "foo"},
response: []string{"__name__", "dup", "foo"},
},
// Only provide End within Label names, don't provide a start time.
{
@ -1677,7 +1696,7 @@ func testEndpoints(t *testing.T, api *API, tr *testTargetRetriever, testLabelAPI
query: url.Values{
"end": []string{"20"},
},
response: []string{"__name__", "foo"},
response: []string{"__name__", "dup", "foo"},
},
}...)
}