mirror of
https://github.com/prometheus/prometheus.git
synced 2024-11-09 23:24:05 -08:00
storage: Update LabelQuerier interface to return sorted label values (#14849)
* Change LabelQuerier.LabelValues() to return sorted values --------- Signed-off-by: 🌲 Harry 🌊 John 🏔 <johrry@amazon.com>
This commit is contained in:
parent
2c87817e40
commit
919dc0cbc6
|
@ -157,7 +157,7 @@ type ChunkQuerier interface {
|
||||||
|
|
||||||
// LabelQuerier provides querying access over labels.
|
// LabelQuerier provides querying access over labels.
|
||||||
type LabelQuerier interface {
|
type LabelQuerier interface {
|
||||||
// LabelValues returns all potential values for a label name.
|
// LabelValues returns all potential values for a label name in sorted order.
|
||||||
// It is not safe to use the strings beyond the lifetime of the querier.
|
// It is not safe to use the strings beyond the lifetime of the querier.
|
||||||
// If matchers are specified the returned result set is reduced
|
// If matchers are specified the returned result set is reduced
|
||||||
// to label values of metrics matching the matchers.
|
// to label values of metrics matching the matchers.
|
||||||
|
|
|
@ -22,6 +22,7 @@ import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -310,6 +311,33 @@ func TestLabelValuesWithMatchers(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBlockQuerierReturnsSortedLabelValues(t *testing.T) {
|
||||||
|
tmpdir := t.TempDir()
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
var seriesEntries []storage.Series
|
||||||
|
for i := 100; i > 0; i-- {
|
||||||
|
seriesEntries = append(seriesEntries, storage.NewListSeries(labels.FromStrings(
|
||||||
|
"__name__", fmt.Sprintf("value%d", i),
|
||||||
|
), []chunks.Sample{sample{100, 0, nil, nil}}))
|
||||||
|
}
|
||||||
|
|
||||||
|
blockDir := createBlock(t, tmpdir, seriesEntries)
|
||||||
|
|
||||||
|
// Check open err.
|
||||||
|
block, err := OpenBlock(nil, blockDir, nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
t.Cleanup(func() { require.NoError(t, block.Close()) })
|
||||||
|
|
||||||
|
q, err := newBlockBaseQuerier(block, 0, 100)
|
||||||
|
require.NoError(t, err)
|
||||||
|
t.Cleanup(func() { require.NoError(t, q.Close()) })
|
||||||
|
|
||||||
|
res, _, err := q.LabelValues(ctx, "__name__", nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.True(t, slices.IsSorted(res))
|
||||||
|
}
|
||||||
|
|
||||||
// TestBlockSize ensures that the block size is calculated correctly.
|
// TestBlockSize ensures that the block size is calculated correctly.
|
||||||
func TestBlockSize(t *testing.T) {
|
func TestBlockSize(t *testing.T) {
|
||||||
tmpdir := t.TempDir()
|
tmpdir := t.TempDir()
|
||||||
|
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -2101,6 +2102,36 @@ func TestHead_LogRollback(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHead_ReturnsSortedLabelValues(t *testing.T) {
|
||||||
|
h, _ := newTestHead(t, 1000, wlog.CompressionNone, false)
|
||||||
|
defer func() {
|
||||||
|
require.NoError(t, h.Close())
|
||||||
|
}()
|
||||||
|
|
||||||
|
h.initTime(0)
|
||||||
|
|
||||||
|
app := h.appender()
|
||||||
|
for i := 100; i > 0; i-- {
|
||||||
|
for j := 0; j < 10; j++ {
|
||||||
|
lset := labels.FromStrings(
|
||||||
|
"__name__", fmt.Sprintf("metric_%d", i),
|
||||||
|
"label", fmt.Sprintf("value_%d", j),
|
||||||
|
)
|
||||||
|
_, err := app.Append(0, lset, 2100, 1)
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
q, err := NewBlockQuerier(h, 1500, 2500)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
res, _, err := q.LabelValues(context.Background(), "__name__", nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.True(t, slices.IsSorted(res))
|
||||||
|
require.NoError(t, q.Close())
|
||||||
|
}
|
||||||
|
|
||||||
// TestWalRepair_DecodingError ensures that a repair is run for an error
|
// TestWalRepair_DecodingError ensures that a repair is run for an error
|
||||||
// when decoding a record.
|
// when decoding a record.
|
||||||
func TestWalRepair_DecodingError(t *testing.T) {
|
func TestWalRepair_DecodingError(t *testing.T) {
|
||||||
|
|
Loading…
Reference in a new issue