github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/pkg/storage/stores/tsdb/index_shipper_querier.go (about) 1 package tsdb 2 3 import ( 4 "context" 5 "fmt" 6 "math" 7 8 "github.com/prometheus/common/model" 9 "github.com/prometheus/prometheus/model/labels" 10 11 "github.com/grafana/loki/pkg/storage/chunk" 12 "github.com/grafana/loki/pkg/storage/config" 13 "github.com/grafana/loki/pkg/storage/stores/index/stats" 14 "github.com/grafana/loki/pkg/storage/stores/indexshipper" 15 shipper_index "github.com/grafana/loki/pkg/storage/stores/indexshipper/index" 16 "github.com/grafana/loki/pkg/storage/stores/tsdb/index" 17 ) 18 19 // indexShipperQuerier is used for querying index from the shipper. 20 type indexShipperQuerier struct { 21 shipper indexshipper.IndexShipper 22 chunkFilter chunk.RequestChunkFilterer 23 tableRanges config.TableRanges 24 } 25 26 func newIndexShipperQuerier(shipper indexshipper.IndexShipper, tableRanges config.TableRanges) Index { 27 return &indexShipperQuerier{shipper: shipper, tableRanges: tableRanges} 28 } 29 30 func (i *indexShipperQuerier) indices(ctx context.Context, from, through model.Time, user string) (Index, error) { 31 var indices []Index 32 33 // Ensure we query both per tenant and multitenant TSDBs 34 idxBuckets, err := indexBuckets(from, through, i.tableRanges) 35 if err != nil { 36 return nil, err 37 } 38 for _, bkt := range idxBuckets { 39 if err := i.shipper.ForEach(ctx, bkt, user, func(multitenant bool, idx shipper_index.Index) error { 40 impl, ok := idx.(Index) 41 if !ok { 42 return fmt.Errorf("unexpected shipper index type: %T", idx) 43 } 44 if multitenant { 45 indices = append(indices, NewMultiTenantIndex(impl)) 46 } else { 47 indices = append(indices, impl) 48 } 49 return nil 50 }); err != nil { 51 return nil, err 52 } 53 54 } 55 56 if len(indices) == 0 { 57 return NoopIndex{}, nil 58 } 59 idx, err := NewMultiIndex(indices...) 60 if err != nil { 61 return nil, err 62 } 63 64 if i.chunkFilter != nil { 65 idx.SetChunkFilterer(i.chunkFilter) 66 } 67 return idx, nil 68 } 69 70 // TODO(owen-d): how to better implement this? 71 // setting 0->maxint will force the tsdbmanager to always query 72 // underlying tsdbs, which is safe, but can we optimize this? 73 func (i *indexShipperQuerier) Bounds() (model.Time, model.Time) { 74 return 0, math.MaxInt64 75 } 76 77 func (i *indexShipperQuerier) SetChunkFilterer(chunkFilter chunk.RequestChunkFilterer) { 78 i.chunkFilter = chunkFilter 79 } 80 81 // Close implements Index.Close, but we offload this responsibility 82 // to the index shipper 83 func (i *indexShipperQuerier) Close() error { 84 return nil 85 } 86 87 func (i *indexShipperQuerier) GetChunkRefs(ctx context.Context, userID string, from, through model.Time, res []ChunkRef, shard *index.ShardAnnotation, matchers ...*labels.Matcher) ([]ChunkRef, error) { 88 idx, err := i.indices(ctx, from, through, userID) 89 if err != nil { 90 return nil, err 91 } 92 return idx.GetChunkRefs(ctx, userID, from, through, res, shard, matchers...) 93 } 94 95 func (i *indexShipperQuerier) Series(ctx context.Context, userID string, from, through model.Time, res []Series, shard *index.ShardAnnotation, matchers ...*labels.Matcher) ([]Series, error) { 96 idx, err := i.indices(ctx, from, through, userID) 97 if err != nil { 98 return nil, err 99 } 100 return idx.Series(ctx, userID, from, through, res, shard, matchers...) 101 } 102 103 func (i *indexShipperQuerier) LabelNames(ctx context.Context, userID string, from, through model.Time, matchers ...*labels.Matcher) ([]string, error) { 104 idx, err := i.indices(ctx, from, through, userID) 105 if err != nil { 106 return nil, err 107 } 108 return idx.LabelNames(ctx, userID, from, through, matchers...) 109 } 110 111 func (i *indexShipperQuerier) LabelValues(ctx context.Context, userID string, from, through model.Time, name string, matchers ...*labels.Matcher) ([]string, error) { 112 idx, err := i.indices(ctx, from, through, userID) 113 if err != nil { 114 return nil, err 115 } 116 return idx.LabelValues(ctx, userID, from, through, name, matchers...) 117 } 118 119 func (i *indexShipperQuerier) Stats(ctx context.Context, userID string, from, through model.Time, blooms *stats.Blooms, shard *index.ShardAnnotation, matchers ...*labels.Matcher) (*stats.Blooms, error) { 120 idx, err := i.indices(ctx, from, through, userID) 121 if err != nil { 122 return blooms, err 123 } 124 125 return idx.Stats(ctx, userID, from, through, blooms, shard, matchers...) 126 }