mirror of
https://github.com/prometheus/prometheus.git
synced 2025-03-05 20:59:13 -08:00
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:
parent
085352ba97
commit
dfdc358a5b
|
@ -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() {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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"},
|
||||
},
|
||||
}...)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue