Skip to content

Commit 5b87056

Browse files
gouthamveOghenebrume50
authored andcommitted
[store] Add response hints to label APIs (thanos-io#3437)
* Add hints support to labels API responses Signed-off-by: Goutham Veeramachaneni <[email protected]> * Move to dedicated hints types and add tests Signed-off-by: Goutham Veeramachaneni <[email protected]> * Add external labels to the values returned in API Signed-off-by: Goutham Veeramachaneni <[email protected]> * Add changelog entries Fixes thanos-io#2984 Signed-off-by: Goutham Veeramachaneni <[email protected]> Signed-off-by: Oghenebrume50 <[email protected]>
1 parent 7606d01 commit 5b87056

File tree

9 files changed

+836
-153
lines changed

9 files changed

+836
-153
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,15 @@ We use _breaking :warning:_ to mark changes that are not backward compatible (re
3131
- [#3423](https://github.com/thanos-io/thanos/pull/3423) UI: Thanos Configurations file page: Display all available configuration for each component on the UI.
3232
- [#3431](https://github.com/thanos-io/thanos/pull/3431) Store: Added experimental support to lazy load index-headers at query time. When enabled via `--store.enable-index-header-lazy-reader` flag, the store-gateway will load into memory an index-header only once it's required at query time. Index-header will be automatically released after `--store.index-header-lazy-reader-idle-timeout` of inactivity.
3333
- This, generally, reduces baseline memory usage of store when inactive, as well as a total number of mapped files (which is limited to 64k in some systems.
34+
- [#3437](https://github.com/thanos-io/thanos/pull/3437) StoreAPI: Added `hints` field to `LabelNamesResponse` and `LabelValuesResponse`. Hints in an opaque data structure that can be used to carry additional information from the store and its content is implementation specific.
3435

3536
### Fixed
3637

3738
- [#3257](https://github.com/thanos-io/thanos/pull/3257) Ruler: Prevent Ruler from crashing when using default DNS to lookup hosts that results in "No such hosts" errors.
3839
- [#3331](https://github.com/thanos-io/thanos/pull/3331) Disable Azure blob exception logging
3940
- [#3341](https://github.com/thanos-io/thanos/pull/3341) Disable Azure blob syslog exception logging
4041
- [#3414](https://github.com/thanos-io/thanos/pull/3414) Set CORS for Query Frontend
42+
- [#3437](https://github.com/thanos-io/thanos/pull/3437) Add external labels to Labels APIs.
4143

4244
### Changed
4345

pkg/store/bucket.go

+43
Original file line numberDiff line numberDiff line change
@@ -1066,6 +1066,8 @@ func chunksSize(chks []storepb.AggrChunk) (size int) {
10661066

10671067
// LabelNames implements the storepb.StoreServer interface.
10681068
func (s *BucketStore) LabelNames(ctx context.Context, req *storepb.LabelNamesRequest) (*storepb.LabelNamesResponse, error) {
1069+
resHints := &hintspb.LabelNamesResponseHints{}
1070+
10691071
g, gctx := errgroup.WithContext(ctx)
10701072

10711073
s.mtx.RLock()
@@ -1077,7 +1079,12 @@ func (s *BucketStore) LabelNames(ctx context.Context, req *storepb.LabelNamesReq
10771079
if !b.overlapsClosedInterval(req.Start, req.End) {
10781080
continue
10791081
}
1082+
1083+
resHints.AddQueriedBlock(b.meta.ULID)
1084+
10801085
indexr := b.indexReader(gctx)
1086+
extLabels := b.meta.Thanos.Labels
1087+
10811088
g.Go(func() error {
10821089
defer runutil.CloseWithLogOnErr(s.logger, indexr, "label names")
10831090

@@ -1087,7 +1094,17 @@ func (s *BucketStore) LabelNames(ctx context.Context, req *storepb.LabelNamesReq
10871094
return errors.Wrap(err, "label names")
10881095
}
10891096

1097+
// Add a set for the external labels as well.
1098+
// We're not adding them directly to res because there could be duplicates.
1099+
extRes := make([]string, 0, len(extLabels))
1100+
for lName := range extLabels {
1101+
extRes = append(extRes, lName)
1102+
}
1103+
10901104
sort.Strings(res)
1105+
sort.Strings(extRes)
1106+
1107+
res = strutil.MergeSlices(res, extRes)
10911108

10921109
mtx.Lock()
10931110
sets = append(sets, res)
@@ -1102,13 +1119,22 @@ func (s *BucketStore) LabelNames(ctx context.Context, req *storepb.LabelNamesReq
11021119
if err := g.Wait(); err != nil {
11031120
return nil, status.Error(codes.Internal, err.Error())
11041121
}
1122+
1123+
anyHints, err := types.MarshalAny(resHints)
1124+
if err != nil {
1125+
return nil, status.Error(codes.Unknown, errors.Wrap(err, "marshal label names response hints").Error())
1126+
}
1127+
11051128
return &storepb.LabelNamesResponse{
11061129
Names: strutil.MergeSlices(sets...),
1130+
Hints: anyHints,
11071131
}, nil
11081132
}
11091133

11101134
// LabelValues implements the storepb.StoreServer interface.
11111135
func (s *BucketStore) LabelValues(ctx context.Context, req *storepb.LabelValuesRequest) (*storepb.LabelValuesResponse, error) {
1136+
resHints := &hintspb.LabelValuesResponseHints{}
1137+
11121138
g, gctx := errgroup.WithContext(ctx)
11131139

11141140
s.mtx.RLock()
@@ -1120,7 +1146,12 @@ func (s *BucketStore) LabelValues(ctx context.Context, req *storepb.LabelValuesR
11201146
if !b.overlapsClosedInterval(req.Start, req.End) {
11211147
continue
11221148
}
1149+
1150+
resHints.AddQueriedBlock(b.meta.ULID)
1151+
11231152
indexr := b.indexReader(gctx)
1153+
extLabels := b.meta.Thanos.Labels
1154+
11241155
g.Go(func() error {
11251156
defer runutil.CloseWithLogOnErr(s.logger, indexr, "label values")
11261157

@@ -1130,6 +1161,11 @@ func (s *BucketStore) LabelValues(ctx context.Context, req *storepb.LabelValuesR
11301161
return errors.Wrap(err, "index header label values")
11311162
}
11321163

1164+
// Add the external label value as well.
1165+
if extLabelValue, ok := extLabels[req.Label]; ok {
1166+
res = strutil.MergeSlices(res, []string{extLabelValue})
1167+
}
1168+
11331169
mtx.Lock()
11341170
sets = append(sets, res)
11351171
mtx.Unlock()
@@ -1143,8 +1179,15 @@ func (s *BucketStore) LabelValues(ctx context.Context, req *storepb.LabelValuesR
11431179
if err := g.Wait(); err != nil {
11441180
return nil, status.Error(codes.Aborted, err.Error())
11451181
}
1182+
1183+
anyHints, err := types.MarshalAny(resHints)
1184+
if err != nil {
1185+
return nil, status.Error(codes.Unknown, errors.Wrap(err, "marshal label values response hints").Error())
1186+
}
1187+
11461188
return &storepb.LabelValuesResponse{
11471189
Values: strutil.MergeSlices(sets...),
1190+
Hints: anyHints,
11481191
}, nil
11491192
}
11501193

pkg/store/bucket_e2e_test.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,8 @@ func TestBucketStore_LabelNames_e2e(t *testing.T) {
629629
End: timestamp.FromTime(maxTime),
630630
})
631631
testutil.Ok(t, err)
632-
testutil.Equals(t, []string{"a", "b", "c"}, vals.Names)
632+
// ext2 is added by the prepareStoreWithTestBlocks function.
633+
testutil.Equals(t, []string{"a", "b", "c", "ext1", "ext2"}, vals.Names)
633634

634635
// Outside the time range.
635636
vals, err = s.store.LabelNames(ctx, &storepb.LabelNamesRequest{

0 commit comments

Comments
 (0)