Skip to content

Commit 2b01472

Browse files
committed
Add matchers to LabelNames() ingester RPC
Signed-off-by: 🌲 Harry 🌊 John 🏔 <[email protected]>
1 parent f74b4cd commit 2b01472

File tree

11 files changed

+262
-147
lines changed

11 files changed

+262
-147
lines changed

pkg/distributor/distributor.go

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,7 +1101,7 @@ func (d *Distributor) LabelValuesForLabelNameStream(ctx context.Context, from, t
11011101
}, matchers...)
11021102
}
11031103

1104-
func (d *Distributor) LabelNamesCommon(ctx context.Context, from, to model.Time, hints *storage.LabelHints, f func(ctx context.Context, rs ring.ReplicationSet, req *ingester_client.LabelNamesRequest) ([]interface{}, error)) ([]string, error) {
1104+
func (d *Distributor) LabelNamesCommon(ctx context.Context, from, to model.Time, hints *storage.LabelHints, f func(ctx context.Context, rs ring.ReplicationSet, req *ingester_client.LabelNamesRequest) ([]interface{}, error), matchers ...*labels.Matcher) ([]string, error) {
11051105
span, ctx := opentracing.StartSpanFromContext(ctx, "Distributor.LabelNames", opentracing.Tags{
11061106
"start": from.Unix(),
11071107
"end": to.Unix(),
@@ -1113,11 +1113,7 @@ func (d *Distributor) LabelNamesCommon(ctx context.Context, from, to model.Time,
11131113
}
11141114

11151115
limit := getLimitFromLabelHints(hints)
1116-
req := &ingester_client.LabelNamesRequest{
1117-
StartTimestampMs: int64(from),
1118-
EndTimestampMs: int64(to),
1119-
Limit: int64(limit),
1120-
}
1116+
req, err := ingester_client.ToLabelNamesRequest(from, to, limit, matchers)
11211117
resps, err := f(ctx, replicationSet, req)
11221118
if err != nil {
11231119
return nil, err
@@ -1142,7 +1138,7 @@ func (d *Distributor) LabelNamesCommon(ctx context.Context, from, to model.Time,
11421138
return r, nil
11431139
}
11441140

1145-
func (d *Distributor) LabelNamesStream(ctx context.Context, from, to model.Time, hints *storage.LabelHints) ([]string, error) {
1141+
func (d *Distributor) LabelNamesStream(ctx context.Context, from, to model.Time, hints *storage.LabelHints, matchers ...*labels.Matcher) ([]string, error) {
11461142
return d.LabelNamesCommon(ctx, from, to, hints, func(ctx context.Context, rs ring.ReplicationSet, req *ingester_client.LabelNamesRequest) ([]interface{}, error) {
11471143
return d.ForReplicationSet(ctx, rs, d.cfg.ZoneResultsQuorumMetadata, func(ctx context.Context, client ingester_client.IngesterClient) (interface{}, error) {
11481144
stream, err := client.LabelNamesStream(ctx, req)
@@ -1164,11 +1160,11 @@ func (d *Distributor) LabelNamesStream(ctx context.Context, from, to model.Time,
11641160

11651161
return allLabelNames, nil
11661162
})
1167-
})
1163+
}, matchers...)
11681164
}
11691165

11701166
// LabelNames returns all the label names.
1171-
func (d *Distributor) LabelNames(ctx context.Context, from, to model.Time, hint *storage.LabelHints) ([]string, error) {
1167+
func (d *Distributor) LabelNames(ctx context.Context, from, to model.Time, hint *storage.LabelHints, matchers ...*labels.Matcher) ([]string, error) {
11721168
return d.LabelNamesCommon(ctx, from, to, hint, func(ctx context.Context, rs ring.ReplicationSet, req *ingester_client.LabelNamesRequest) ([]interface{}, error) {
11731169
return d.ForReplicationSet(ctx, rs, d.cfg.ZoneResultsQuorumMetadata, func(ctx context.Context, client ingester_client.IngesterClient) (interface{}, error) {
11741170
resp, err := client.LabelNames(ctx, req)
@@ -1177,7 +1173,7 @@ func (d *Distributor) LabelNames(ctx context.Context, from, to model.Time, hint
11771173
}
11781174
return resp.LabelNames, nil
11791175
})
1180-
})
1176+
}, matchers...)
11811177
}
11821178

11831179
// MetricsForLabelMatchers gets the metrics that match said matchers

pkg/ingester/client/compat.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,36 @@ func FromLabelValuesRequest(req *LabelValuesRequest) (string, int64, int64, int,
220220
return req.LabelName, req.StartTimestampMs, req.EndTimestampMs, int(req.Limit), matchers, nil
221221
}
222222

223+
// ToLabelNamesRequest builds a LabelNamesRequest proto
224+
func ToLabelNamesRequest(from, to model.Time, limit int, matchers []*labels.Matcher) (*LabelNamesRequest, error) {
225+
ms, err := toLabelMatchers(matchers)
226+
if err != nil {
227+
return nil, err
228+
}
229+
230+
return &LabelNamesRequest{
231+
StartTimestampMs: int64(from),
232+
EndTimestampMs: int64(to),
233+
Matchers: &LabelMatchers{Matchers: ms},
234+
Limit: int64(limit),
235+
}, nil
236+
}
237+
238+
// FromLabelNamesRequest unpacks a LabelNamesRequest proto
239+
func FromLabelNamesRequest(req *LabelNamesRequest) (int64, int64, int, []*labels.Matcher, error) {
240+
var err error
241+
var matchers []*labels.Matcher
242+
243+
if req.Matchers != nil {
244+
matchers, err = FromLabelMatchers(req.Matchers.Matchers)
245+
if err != nil {
246+
return 0, 0, 0, nil, err
247+
}
248+
}
249+
250+
return req.StartTimestampMs, req.EndTimestampMs, int(req.Limit), matchers, nil
251+
}
252+
223253
func toLabelMatchers(matchers []*labels.Matcher) ([]*LabelMatcher, error) {
224254
result := make([]*LabelMatcher, 0, len(matchers))
225255
for _, matcher := range matchers {

pkg/ingester/client/ingester.pb.go

Lines changed: 156 additions & 88 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/ingester/client/ingester.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ message LabelNamesRequest {
8282
int64 start_timestamp_ms = 1;
8383
int64 end_timestamp_ms = 2;
8484
int64 limit = 3;
85+
LabelMatchers matchers = 4;
8586
}
8687

8788
message LabelNamesResponse {

pkg/ingester/ingester.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1591,6 +1591,11 @@ func (i *Ingester) labelNamesCommon(ctx context.Context, req *client.LabelNamesR
15911591
return nil, cleanup, err
15921592
}
15931593

1594+
startTimestampMs, endTimestampMs, limit, matchers, err := client.FromLabelNamesRequest(req)
1595+
if err != nil {
1596+
return nil, cleanup, err
1597+
}
1598+
15941599
userID, err := tenant.TenantID(ctx)
15951600
if err != nil {
15961601
return nil, cleanup, err
@@ -1601,13 +1606,11 @@ func (i *Ingester) labelNamesCommon(ctx context.Context, req *client.LabelNamesR
16011606
return &client.LabelNamesResponse{}, cleanup, nil
16021607
}
16031608

1604-
mint, maxt, err := metadataQueryRange(req.StartTimestampMs, req.EndTimestampMs, db, i.cfg.QueryIngestersWithin)
1609+
mint, maxt, err := metadataQueryRange(startTimestampMs, endTimestampMs, db, i.cfg.QueryIngestersWithin)
16051610
if err != nil {
16061611
return nil, cleanup, err
16071612
}
16081613

1609-
limit := int(req.Limit)
1610-
16111614
q, err := db.Querier(mint, maxt)
16121615
if err != nil {
16131616
return nil, cleanup, err
@@ -1622,7 +1625,7 @@ func (i *Ingester) labelNamesCommon(ctx context.Context, req *client.LabelNamesR
16221625
return nil, cleanup, err
16231626
}
16241627
defer c()
1625-
names, _, err := q.LabelNames(ctx, &storage.LabelHints{Limit: limit})
1628+
names, _, err := q.LabelNames(ctx, &storage.LabelHints{Limit: limit}, matchers...)
16261629
if err != nil {
16271630
return nil, cleanup, err
16281631
}

pkg/ingester/ingester_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2302,6 +2302,7 @@ func Test_Ingester_LabelValues(t *testing.T) {
23022302

23032303
tests := map[string]struct {
23042304
limit int64
2305+
match []*labels.Matcher
23052306
}{
23062307
"should return all label values if no limit is set": {
23072308
limit: 0,

pkg/querier/distributor_queryable.go

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,27 +29,29 @@ type Distributor interface {
2929
QueryExemplars(ctx context.Context, from, to model.Time, matchers ...[]*labels.Matcher) (*client.ExemplarQueryResponse, error)
3030
LabelValuesForLabelName(ctx context.Context, from, to model.Time, label model.LabelName, hint *storage.LabelHints, matchers ...*labels.Matcher) ([]string, error)
3131
LabelValuesForLabelNameStream(ctx context.Context, from, to model.Time, label model.LabelName, hint *storage.LabelHints, matchers ...*labels.Matcher) ([]string, error)
32-
LabelNames(context.Context, model.Time, model.Time, *storage.LabelHints) ([]string, error)
33-
LabelNamesStream(context.Context, model.Time, model.Time, *storage.LabelHints) ([]string, error)
32+
LabelNames(context.Context, model.Time, model.Time, *storage.LabelHints, ...*labels.Matcher) ([]string, error)
33+
LabelNamesStream(context.Context, model.Time, model.Time, *storage.LabelHints, ...*labels.Matcher) ([]string, error)
3434
MetricsForLabelMatchers(ctx context.Context, from, through model.Time, hint *storage.SelectHints, matchers ...*labels.Matcher) ([]model.Metric, error)
3535
MetricsForLabelMatchersStream(ctx context.Context, from, through model.Time, hint *storage.SelectHints, matchers ...*labels.Matcher) ([]model.Metric, error)
3636
MetricsMetadata(ctx context.Context) ([]scrape.MetricMetadata, error)
3737
}
3838

39-
func newDistributorQueryable(distributor Distributor, streamingMetdata bool, iteratorFn chunkIteratorFunc, queryIngestersWithin time.Duration) QueryableWithFilter {
39+
func newDistributorQueryable(distributor Distributor, streamingMetdata bool, labelNamesWithMatchers bool, iteratorFn chunkIteratorFunc, queryIngestersWithin time.Duration) QueryableWithFilter {
4040
return distributorQueryable{
41-
distributor: distributor,
42-
streamingMetdata: streamingMetdata,
43-
iteratorFn: iteratorFn,
44-
queryIngestersWithin: queryIngestersWithin,
41+
distributor: distributor,
42+
streamingMetdata: streamingMetdata,
43+
labelNamesWithMatchers: labelNamesWithMatchers,
44+
iteratorFn: iteratorFn,
45+
queryIngestersWithin: queryIngestersWithin,
4546
}
4647
}
4748

4849
type distributorQueryable struct {
49-
distributor Distributor
50-
streamingMetdata bool
51-
iteratorFn chunkIteratorFunc
52-
queryIngestersWithin time.Duration
50+
distributor Distributor
51+
streamingMetdata bool
52+
labelNamesWithMatchers bool
53+
iteratorFn chunkIteratorFunc
54+
queryIngestersWithin time.Duration
5355
}
5456

5557
func (d distributorQueryable) Querier(mint, maxt int64) (storage.Querier, error) {
@@ -58,6 +60,7 @@ func (d distributorQueryable) Querier(mint, maxt int64) (storage.Querier, error)
5860
mint: mint,
5961
maxt: maxt,
6062
streamingMetadata: d.streamingMetdata,
63+
labelNamesMatchers: d.labelNamesWithMatchers,
6164
chunkIterFn: d.iteratorFn,
6265
queryIngestersWithin: d.queryIngestersWithin,
6366
}, nil
@@ -72,6 +75,7 @@ type distributorQuerier struct {
7275
distributor Distributor
7376
mint, maxt int64
7477
streamingMetadata bool
78+
labelNamesMatchers bool
7579
chunkIterFn chunkIteratorFunc
7680
queryIngestersWithin time.Duration
7781
}
@@ -180,7 +184,7 @@ func (q *distributorQuerier) LabelValues(ctx context.Context, name string, hints
180184
}
181185

182186
func (q *distributorQuerier) LabelNames(ctx context.Context, hints *storage.LabelHints, matchers ...*labels.Matcher) ([]string, annotations.Annotations, error) {
183-
if len(matchers) > 0 {
187+
if len(matchers) > 0 && !q.labelNamesMatchers {
184188
return q.labelNamesWithMatchers(ctx, hints, matchers...)
185189
}
186190

@@ -193,9 +197,9 @@ func (q *distributorQuerier) LabelNames(ctx context.Context, hints *storage.Labe
193197
)
194198

195199
if q.streamingMetadata {
196-
ln, err = q.distributor.LabelNamesStream(ctx, model.Time(q.mint), model.Time(q.maxt), hints)
200+
ln, err = q.distributor.LabelNamesStream(ctx, model.Time(q.mint), model.Time(q.maxt), hints, matchers...)
197201
} else {
198-
ln, err = q.distributor.LabelNames(ctx, model.Time(q.mint), model.Time(q.maxt), hints)
202+
ln, err = q.distributor.LabelNames(ctx, model.Time(q.mint), model.Time(q.maxt), hints, matchers...)
199203
}
200204

201205
return ln, nil, err

pkg/querier/distributor_queryable_test.go

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ func TestDistributorQuerier_SelectShouldHonorQueryIngestersWithin(t *testing.T)
8989
distributor.On("MetricsForLabelMatchersStream", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]model.Metric{}, nil)
9090

9191
ctx := user.InjectOrgID(context.Background(), "test")
92-
queryable := newDistributorQueryable(distributor, streamingMetadataEnabled, nil, testData.queryIngestersWithin)
92+
queryable := newDistributorQueryable(distributor, streamingMetadataEnabled, true, nil, testData.queryIngestersWithin)
9393
querier, err := queryable.Querier(testData.queryMinT, testData.queryMaxT)
9494
require.NoError(t, err)
9595

@@ -128,7 +128,7 @@ func TestDistributorQueryableFilter(t *testing.T) {
128128
t.Parallel()
129129

130130
d := &MockDistributor{}
131-
dq := newDistributorQueryable(d, false, nil, 1*time.Hour)
131+
dq := newDistributorQueryable(d, false, true, nil, 1*time.Hour)
132132

133133
now := time.Now()
134134

@@ -172,7 +172,7 @@ func TestIngesterStreaming(t *testing.T) {
172172
nil)
173173

174174
ctx := user.InjectOrgID(context.Background(), "0")
175-
queryable := newDistributorQueryable(d, true, batch.NewChunkMergeIterator, 0)
175+
queryable := newDistributorQueryable(d, true, true, batch.NewChunkMergeIterator, 0)
176176
querier, err := queryable.Querier(mint, maxt)
177177
require.NoError(t, err)
178178

@@ -202,23 +202,33 @@ func TestDistributorQuerier_LabelNames(t *testing.T) {
202202
someMatchers := []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "foo", "bar")}
203203
labelNames := []string{"foo", "job"}
204204

205-
for _, streamingEnabled := range []bool{false, true} {
206-
streamingEnabled := streamingEnabled
205+
for _, enabled := range []bool{false, true} {
206+
streamingEnabled := enabled
207+
labelNamesWithMatchers := enabled
207208
t.Run("with matchers", func(t *testing.T) {
208-
t.Parallel()
209+
//t.Parallel()
209210

210211
metrics := []model.Metric{
211212
{"foo": "bar"},
212213
{"job": "baz"},
213214
{"job": "baz", "foo": "boom"},
214215
}
215216
d := &MockDistributor{}
216-
d.On("MetricsForLabelMatchers", mock.Anything, model.Time(mint), model.Time(maxt), mock.Anything, someMatchers).
217-
Return(metrics, nil)
218-
d.On("MetricsForLabelMatchersStream", mock.Anything, model.Time(mint), model.Time(maxt), mock.Anything, someMatchers).
219-
Return(metrics, nil)
220217

221-
queryable := newDistributorQueryable(d, streamingEnabled, nil, 0)
218+
if labelNamesWithMatchers {
219+
// ln, err = q.distributor.LabelNames(ctx, model.Time(q.mint), model.Time(q.maxt), hints, matchers...)
220+
d.On("LabelNames", mock.Anything, model.Time(mint), model.Time(maxt), mock.Anything, someMatchers).
221+
Return(labelNames, nil)
222+
d.On("LabelNamesStream", mock.Anything, model.Time(mint), model.Time(maxt), mock.Anything, someMatchers).
223+
Return(labelNames, nil)
224+
} else {
225+
d.On("MetricsForLabelMatchers", mock.Anything, model.Time(mint), model.Time(maxt), mock.Anything, someMatchers).
226+
Return(metrics, nil)
227+
d.On("MetricsForLabelMatchersStream", mock.Anything, model.Time(mint), model.Time(maxt), mock.Anything, someMatchers).
228+
Return(metrics, nil)
229+
}
230+
231+
queryable := newDistributorQueryable(d, streamingEnabled, labelNamesWithMatchers, nil, 0)
222232
querier, err := queryable.Querier(mint, maxt)
223233
require.NoError(t, err)
224234

pkg/querier/querier.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,14 @@ import (
4141

4242
// Config contains the configuration require to create a querier
4343
type Config struct {
44-
MaxConcurrent int `yaml:"max_concurrent"`
45-
Timeout time.Duration `yaml:"timeout"`
46-
IngesterStreaming bool `yaml:"ingester_streaming" doc:"hidden"`
47-
IngesterMetadataStreaming bool `yaml:"ingester_metadata_streaming"`
48-
MaxSamples int `yaml:"max_samples"`
49-
QueryIngestersWithin time.Duration `yaml:"query_ingesters_within"`
50-
EnablePerStepStats bool `yaml:"per_step_stats_enabled"`
44+
MaxConcurrent int `yaml:"max_concurrent"`
45+
Timeout time.Duration `yaml:"timeout"`
46+
IngesterStreaming bool `yaml:"ingester_streaming" doc:"hidden"`
47+
IngesterMetadataStreaming bool `yaml:"ingester_metadata_streaming"`
48+
IngesterLabelNamesWithMatchers bool `yaml:"ingester_label_names_with_matchers"`
49+
MaxSamples int `yaml:"max_samples"`
50+
QueryIngestersWithin time.Duration `yaml:"query_ingesters_within"`
51+
EnablePerStepStats bool `yaml:"per_step_stats_enabled"`
5152

5253
// QueryStoreAfter the time after which queries should also be sent to the store and not just ingesters.
5354
QueryStoreAfter time.Duration `yaml:"query_store_after"`
@@ -106,6 +107,7 @@ func (cfg *Config) RegisterFlags(f *flag.FlagSet) {
106107
f.IntVar(&cfg.MaxConcurrent, "querier.max-concurrent", 20, "The maximum number of concurrent queries.")
107108
f.DurationVar(&cfg.Timeout, "querier.timeout", 2*time.Minute, "The timeout for a query.")
108109
f.BoolVar(&cfg.IngesterMetadataStreaming, "querier.ingester-metadata-streaming", true, "Deprecated (This feature will be always on after v1.18): Use streaming RPCs for metadata APIs from ingester.")
110+
f.BoolVar(&cfg.IngesterLabelNamesWithMatchers, "querier.ingester-label-names-with-matchers", false, "Use LabelNames ingester RPCs with match params.")
109111
f.IntVar(&cfg.MaxSamples, "querier.max-samples", 50e6, "Maximum number of samples a single query can load into memory.")
110112
f.DurationVar(&cfg.QueryIngestersWithin, "querier.query-ingesters-within", 0, "Maximum lookback beyond which queries are not sent to ingester. 0 means all queries are sent to ingester.")
111113
f.BoolVar(&cfg.EnablePerStepStats, "querier.per-step-stats-enabled", false, "Enable returning samples stats per steps in query response.")
@@ -156,7 +158,7 @@ func getChunksIteratorFunction(_ Config) chunkIteratorFunc {
156158
func New(cfg Config, limits *validation.Overrides, distributor Distributor, stores []QueryableWithFilter, reg prometheus.Registerer, logger log.Logger) (storage.SampleAndChunkQueryable, storage.ExemplarQueryable, promql.QueryEngine) {
157159
iteratorFunc := getChunksIteratorFunction(cfg)
158160

159-
distributorQueryable := newDistributorQueryable(distributor, cfg.IngesterMetadataStreaming, iteratorFunc, cfg.QueryIngestersWithin)
161+
distributorQueryable := newDistributorQueryable(distributor, cfg.IngesterMetadataStreaming, cfg.IngesterLabelNamesWithMatchers, iteratorFunc, cfg.QueryIngestersWithin)
160162

161163
ns := make([]QueryableWithFilter, len(stores))
162164
for ix, s := range stores {

0 commit comments

Comments
 (0)