From 25b0a4297c4aad7f857f7bb9815c35300400bf63 Mon Sep 17 00:00:00 2001 From: Oleg Zaytsev Date: Mon, 26 Jul 2021 18:06:36 +0200 Subject: [PATCH] Upgrade Prometheus and Cortex This bumps prometheus up to the changes from https://github.com/prometheus/prometheus/pull/9083 and Cortex to https://github.com/cortexproject/cortex/pull/4380 Signed-off-by: Oleg Zaytsev --- go.mod | 4 +- go.sum | 8 +- pkg/ruler/memstore.go | 2 +- .../cortex/pkg/distributor/distributor.go | 5 +- .../cortex/pkg/ingester/ingester.go | 72 +++++++++-------- .../cortex/pkg/ingester/ingester_v2.go | 36 +++++++++ .../pkg/querier/blocks_store_queryable.go | 31 +++++--- .../pkg/querier/chunk_store_queryable.go | 2 +- .../pkg/querier/distributor_queryable.go | 37 ++++++++- .../pkg/querier/error_translate_queryable.go | 8 +- .../cortex/pkg/querier/lazyquery/lazyquery.go | 4 +- .../cortex/pkg/querier/querier.go | 8 +- .../pkg/querier/queryrange/queryable.go | 2 +- .../pkg/querier/queryrange/test_utils.go | 2 +- .../tenantfederation/merge_queryable.go | 52 ++++++------- .../prometheus/storage/interface.go | 5 +- .../prometheus/prometheus/storage/merge.go | 4 +- .../prometheus/prometheus/storage/noop.go | 4 +- .../prometheus/storage/remote/read.go | 2 +- .../prometheus/storage/secondary.go | 4 +- .../prometheus/prometheus/tsdb/block.go | 26 +++++-- .../prometheus/prometheus/tsdb/head.go | 38 +++++++-- .../prometheus/prometheus/tsdb/index/index.go | 77 ++++++++++++++++++- .../prometheus/prometheus/tsdb/querier.go | 21 ++++- .../prometheus/prometheus/web/api/v1/api.go | 26 +++---- vendor/modules.txt | 4 +- 26 files changed, 345 insertions(+), 139 deletions(-) diff --git a/go.mod b/go.mod index ef126195ab74..830229b2280e 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee github.com/cespare/xxhash/v2 v2.1.1 github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf - github.com/cortexproject/cortex v1.9.1-0.20210722081137-485474c9afb2 + github.com/cortexproject/cortex v1.9.1-0.20210726155107-a4bf10354786 github.com/davecgh/go-spew v1.1.1 github.com/docker/docker v20.10.7+incompatible github.com/docker/go-plugins-helpers v0.0.0-20181025120712-1e6269c305b8 @@ -55,7 +55,7 @@ require ( github.com/prometheus/client_golang v1.11.0 github.com/prometheus/client_model v0.2.0 github.com/prometheus/common v0.29.0 - github.com/prometheus/prometheus v1.8.2-0.20210720084720-59d02b5ef003 + github.com/prometheus/prometheus v1.8.2-0.20210720123808-b1ed4a0a663d github.com/segmentio/fasthash v1.0.2 github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 diff --git a/go.sum b/go.sum index 10b36399b3b9..94eee4eeb9b4 100644 --- a/go.sum +++ b/go.sum @@ -491,8 +491,8 @@ github.com/cortexproject/cortex v1.6.1-0.20210215155036-dfededd9f331/go.mod h1:8 github.com/cortexproject/cortex v1.7.1-0.20210224085859-66d6fb5b0d42/go.mod h1:u2dxcHInYbe45wxhLoWVdlFJyDhXewsMcxtnbq/QbH4= github.com/cortexproject/cortex v1.7.1-0.20210316085356-3fedc1108a49/go.mod h1:/DBOW8TzYBTE/U+O7Whs7i7E2eeeZl1iRVDtIqxn5kg= github.com/cortexproject/cortex v1.8.1-0.20210422151339-cf1c444e0905/go.mod h1:xxm4/CLvTmDxwE7yXwtClR4dIvkG4S09o5DygPOgc1U= -github.com/cortexproject/cortex v1.9.1-0.20210722081137-485474c9afb2 h1:zOmlCaoej8fpmvcSU401lWp32kQ7nD8BOjwKq5y7yuk= -github.com/cortexproject/cortex v1.9.1-0.20210722081137-485474c9afb2/go.mod h1:AHNw98b1RQDjDkt1A3/AO7qQGfKLlpAZ8ocsMCOtZvo= +github.com/cortexproject/cortex v1.9.1-0.20210726155107-a4bf10354786 h1:AIwk+TdXdOKD8KVkDAo4txZ3ozHmmnbe7wJoiT3USPU= +github.com/cortexproject/cortex v1.9.1-0.20210726155107-a4bf10354786/go.mod h1:vMkymug9co7+mIu0d5eTkzP8i5v8xOGKke2kUM2Sj08= github.com/couchbase/go-couchbase v0.0.0-20180501122049-16db1f1fe037/go.mod h1:TWI8EKQMs5u5jLKW/tsb9VwauIrMIxQG1r5fMsswK5U= github.com/couchbase/gomemcached v0.0.0-20180502221210-0da75df14530/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c= github.com/couchbase/goutils v0.0.0-20180530154633-e865a1461c8a/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs= @@ -1723,8 +1723,8 @@ github.com/prometheus/prometheus v1.8.2-0.20210215121130-6f488061dfb4/go.mod h1: github.com/prometheus/prometheus v1.8.2-0.20210315220929-1cba1741828b/go.mod h1:MS/bpdil77lPbfQeKk6OqVQ9OLnpN3Rszd0hka0EOWE= github.com/prometheus/prometheus v1.8.2-0.20210324152458-c7a62b95cea0/go.mod h1:sf7j/iAbhZahjeC0s3wwMmp5dksrJ/Za1UKdR+j6Hmw= github.com/prometheus/prometheus v1.8.2-0.20210421143221-52df5ef7a3be/go.mod h1:WbIKsp4vWCoPHis5qQfd0QimLOR7qe79roXN5O8U8bs= -github.com/prometheus/prometheus v1.8.2-0.20210720084720-59d02b5ef003 h1:MYbsDV+OIFLkqwea5oC3jIUp/HxFyXQrvXpw/hooMRQ= -github.com/prometheus/prometheus v1.8.2-0.20210720084720-59d02b5ef003/go.mod h1:o6V+A4iPEWjLG0rSEKeev3OzfBZwP+ay+4iS4dkfLI4= +github.com/prometheus/prometheus v1.8.2-0.20210720123808-b1ed4a0a663d h1:UnqZFF2qXa+ctCfbss/J4yn9rTVoTiuawjrokqwt4Hg= +github.com/prometheus/prometheus v1.8.2-0.20210720123808-b1ed4a0a663d/go.mod h1:o6V+A4iPEWjLG0rSEKeev3OzfBZwP+ay+4iS4dkfLI4= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rafaeljusto/redigomock v0.0.0-20190202135759-257e089e14a1/go.mod h1:JaY6n2sDr+z2WTsXkOmNRUfDy6FN0L6Nk7x06ndm4tY= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= diff --git a/pkg/ruler/memstore.go b/pkg/ruler/memstore.go index 82f0aac9c39a..f73c3c09eb62 100644 --- a/pkg/ruler/memstore.go +++ b/pkg/ruler/memstore.go @@ -313,7 +313,7 @@ func (*memStoreQuerier) LabelValues(name string, matchers ...*labels.Matcher) ([ } // LabelNames returns all the unique label names present in the block in sorted order. -func (*memStoreQuerier) LabelNames() ([]string, storage.Warnings, error) { +func (*memStoreQuerier) LabelNames(matchers ...*labels.Matcher) ([]string, storage.Warnings, error) { return nil, nil, errors.New("unimplemented") } diff --git a/vendor/github.com/cortexproject/cortex/pkg/distributor/distributor.go b/vendor/github.com/cortexproject/cortex/pkg/distributor/distributor.go index ca9039dc5422..92a44cfe7f9a 100644 --- a/vendor/github.com/cortexproject/cortex/pkg/distributor/distributor.go +++ b/vendor/github.com/cortexproject/cortex/pkg/distributor/distributor.go @@ -722,11 +722,12 @@ func (d *Distributor) Push(ctx context.Context, req *cortexpb.WriteRequest) (*co // Ensure the request slice is reused if the request is rate limited. cortexpb.ReuseSlice(req.Timeseries) - // Return a 4xx here to have the client discard the data and not retry. If a client - // is sending too much data consistently we will unlikely ever catch up otherwise. validation.DiscardedSamples.WithLabelValues(validation.RateLimited, userID).Add(float64(validatedSamples)) validation.DiscardedExemplars.WithLabelValues(validation.RateLimited, userID).Add(float64(validatedExemplars)) validation.DiscardedMetadata.WithLabelValues(validation.RateLimited, userID).Add(float64(len(validatedMetadata))) + // Return a 429 here to tell the client it is going too fast. + // Client may discard the data or slow down and re-send. + // Prometheus v2.26 added a remote-write option 'retry_on_http_429'. return nil, httpgrpc.Errorf(http.StatusTooManyRequests, "ingestion rate limit (%v) exceeded while adding %d samples and %d metadata", d.ingestionRateLimiter.Limit(now, userID), validatedSamples, len(validatedMetadata)) } diff --git a/vendor/github.com/cortexproject/cortex/pkg/ingester/ingester.go b/vendor/github.com/cortexproject/cortex/pkg/ingester/ingester.go index 7936a6d3f657..0ee8b1e98abb 100644 --- a/vendor/github.com/cortexproject/cortex/pkg/ingester/ingester.go +++ b/vendor/github.com/cortexproject/cortex/pkg/ingester/ingester.go @@ -480,9 +480,19 @@ func (i *Ingester) checkRunningOrStopping() error { return status.Error(codes.Unavailable, s.String()) } +// Using block store, the ingester is only available when it is in a Running state. The ingester is not available +// when stopping to prevent any read or writes to the TSDB after the ingester has closed them. +func (i *Ingester) checkRunning() error { + s := i.State() + if s == services.Running { + return nil + } + return status.Error(codes.Unavailable, s.String()) +} + // Push implements client.IngesterServer func (i *Ingester) Push(ctx context.Context, req *cortexpb.WriteRequest) (*cortexpb.WriteResponse, error) { - if err := i.checkRunningOrStopping(); err != nil { + if err := i.checkRunning(); err != nil { return nil, err } @@ -762,14 +772,14 @@ func (i *Ingester) purgeUserMetricsMetadata() { // Query implements service.IngesterServer func (i *Ingester) Query(ctx context.Context, req *client.QueryRequest) (*client.QueryResponse, error) { - if err := i.checkRunningOrStopping(); err != nil { - return nil, err - } - if i.cfg.BlocksStorageEnabled { return i.v2Query(ctx, req) } + if err := i.checkRunningOrStopping(); err != nil { + return nil, err + } + userID, err := tenant.TenantID(ctx) if err != nil { return nil, err @@ -829,14 +839,14 @@ func (i *Ingester) Query(ctx context.Context, req *client.QueryRequest) (*client // QueryStream implements service.IngesterServer func (i *Ingester) QueryStream(req *client.QueryRequest, stream client.Ingester_QueryStreamServer) error { - if err := i.checkRunningOrStopping(); err != nil { - return err - } - if i.cfg.BlocksStorageEnabled { return i.v2QueryStream(req, stream) } + if err := i.checkRunningOrStopping(); err != nil { + return err + } + spanLog, ctx := spanlogger.New(stream.Context(), "QueryStream") defer spanLog.Finish() @@ -913,10 +923,6 @@ func (i *Ingester) QueryStream(req *client.QueryRequest, stream client.Ingester_ // Query implements service.IngesterServer func (i *Ingester) QueryExemplars(ctx context.Context, req *client.ExemplarQueryRequest) (*client.ExemplarQueryResponse, error) { - if err := i.checkRunningOrStopping(); err != nil { - return nil, err - } - if !i.cfg.BlocksStorageEnabled { return nil, errors.New("not supported") } @@ -926,14 +932,14 @@ func (i *Ingester) QueryExemplars(ctx context.Context, req *client.ExemplarQuery // LabelValues returns all label values that are associated with a given label name. func (i *Ingester) LabelValues(ctx context.Context, req *client.LabelValuesRequest) (*client.LabelValuesResponse, error) { - if err := i.checkRunningOrStopping(); err != nil { - return nil, err - } - if i.cfg.BlocksStorageEnabled { return i.v2LabelValues(ctx, req) } + if err := i.checkRunningOrStopping(); err != nil { + return nil, err + } + i.userStatesMtx.RLock() defer i.userStatesMtx.RUnlock() state, ok, err := i.userStates.getViaContext(ctx) @@ -951,14 +957,14 @@ func (i *Ingester) LabelValues(ctx context.Context, req *client.LabelValuesReque // LabelNames return all the label names. func (i *Ingester) LabelNames(ctx context.Context, req *client.LabelNamesRequest) (*client.LabelNamesResponse, error) { - if err := i.checkRunningOrStopping(); err != nil { - return nil, err - } - if i.cfg.BlocksStorageEnabled { return i.v2LabelNames(ctx, req) } + if err := i.checkRunningOrStopping(); err != nil { + return nil, err + } + i.userStatesMtx.RLock() defer i.userStatesMtx.RUnlock() state, ok, err := i.userStates.getViaContext(ctx) @@ -976,14 +982,14 @@ func (i *Ingester) LabelNames(ctx context.Context, req *client.LabelNamesRequest // MetricsForLabelMatchers returns all the metrics which match a set of matchers. func (i *Ingester) MetricsForLabelMatchers(ctx context.Context, req *client.MetricsForLabelMatchersRequest) (*client.MetricsForLabelMatchersResponse, error) { - if err := i.checkRunningOrStopping(); err != nil { - return nil, err - } - if i.cfg.BlocksStorageEnabled { return i.v2MetricsForLabelMatchers(ctx, req) } + if err := i.checkRunningOrStopping(); err != nil { + return nil, err + } + i.userStatesMtx.RLock() defer i.userStatesMtx.RUnlock() state, ok, err := i.userStates.getViaContext(ctx) @@ -1046,14 +1052,14 @@ func (i *Ingester) MetricsMetadata(ctx context.Context, req *client.MetricsMetad // UserStats returns ingestion statistics for the current user. func (i *Ingester) UserStats(ctx context.Context, req *client.UserStatsRequest) (*client.UserStatsResponse, error) { - if err := i.checkRunningOrStopping(); err != nil { - return nil, err - } - if i.cfg.BlocksStorageEnabled { return i.v2UserStats(ctx, req) } + if err := i.checkRunningOrStopping(); err != nil { + return nil, err + } + i.userStatesMtx.RLock() defer i.userStatesMtx.RUnlock() state, ok, err := i.userStates.getViaContext(ctx) @@ -1075,14 +1081,14 @@ func (i *Ingester) UserStats(ctx context.Context, req *client.UserStatsRequest) // AllUserStats returns ingestion statistics for all users known to this ingester. func (i *Ingester) AllUserStats(ctx context.Context, req *client.UserStatsRequest) (*client.UsersStatsResponse, error) { - if err := i.checkRunningOrStopping(); err != nil { - return nil, err - } - if i.cfg.BlocksStorageEnabled { return i.v2AllUserStats(ctx, req) } + if err := i.checkRunningOrStopping(); err != nil { + return nil, err + } + i.userStatesMtx.RLock() defer i.userStatesMtx.RUnlock() users := i.userStates.cp() diff --git a/vendor/github.com/cortexproject/cortex/pkg/ingester/ingester_v2.go b/vendor/github.com/cortexproject/cortex/pkg/ingester/ingester_v2.go index d0f2e43c6b33..4b7ecaacce64 100644 --- a/vendor/github.com/cortexproject/cortex/pkg/ingester/ingester_v2.go +++ b/vendor/github.com/cortexproject/cortex/pkg/ingester/ingester_v2.go @@ -980,6 +980,10 @@ func (u *userTSDB) releaseAppendLock() { } func (i *Ingester) v2Query(ctx context.Context, req *client.QueryRequest) (*client.QueryResponse, error) { + if err := i.checkRunning(); err != nil { + return nil, err + } + userID, err := tenant.TenantID(ctx) if err != nil { return nil, err @@ -1036,6 +1040,10 @@ func (i *Ingester) v2Query(ctx context.Context, req *client.QueryRequest) (*clie } func (i *Ingester) v2QueryExemplars(ctx context.Context, req *client.ExemplarQueryRequest) (*client.ExemplarQueryResponse, error) { + if err := i.checkRunning(); err != nil { + return nil, err + } + userID, err := tenant.TenantID(ctx) if err != nil { return nil, err @@ -1083,6 +1091,10 @@ func (i *Ingester) v2QueryExemplars(ctx context.Context, req *client.ExemplarQue } func (i *Ingester) v2LabelValues(ctx context.Context, req *client.LabelValuesRequest) (*client.LabelValuesResponse, error) { + if err := i.checkRunning(); err != nil { + return nil, err + } + labelName, startTimestampMs, endTimestampMs, matchers, err := client.FromLabelValuesRequest(req) if err != nil { return nil, err @@ -1120,6 +1132,10 @@ func (i *Ingester) v2LabelValues(ctx context.Context, req *client.LabelValuesReq } func (i *Ingester) v2LabelNames(ctx context.Context, req *client.LabelNamesRequest) (*client.LabelNamesResponse, error) { + if err := i.checkRunning(); err != nil { + return nil, err + } + userID, err := tenant.TenantID(ctx) if err != nil { return nil, err @@ -1152,6 +1168,10 @@ func (i *Ingester) v2LabelNames(ctx context.Context, req *client.LabelNamesReque } func (i *Ingester) v2MetricsForLabelMatchers(ctx context.Context, req *client.MetricsForLabelMatchersRequest) (*client.MetricsForLabelMatchersResponse, error) { + if err := i.checkRunning(); err != nil { + return nil, err + } + userID, err := tenant.TenantID(ctx) if err != nil { return nil, err @@ -1219,6 +1239,10 @@ func (i *Ingester) v2MetricsForLabelMatchers(ctx context.Context, req *client.Me } func (i *Ingester) v2UserStats(ctx context.Context, req *client.UserStatsRequest) (*client.UserStatsResponse, error) { + if err := i.checkRunning(); err != nil { + return nil, err + } + userID, err := tenant.TenantID(ctx) if err != nil { return nil, err @@ -1233,6 +1257,10 @@ func (i *Ingester) v2UserStats(ctx context.Context, req *client.UserStatsRequest } func (i *Ingester) v2AllUserStats(ctx context.Context, req *client.UserStatsRequest) (*client.UsersStatsResponse, error) { + if err := i.checkRunning(); err != nil { + return nil, err + } + i.userStatesMtx.RLock() defer i.userStatesMtx.RUnlock() @@ -1265,6 +1293,10 @@ const queryStreamBatchMessageSize = 1 * 1024 * 1024 // v2QueryStream streams metrics from a TSDB. This implements the client.IngesterServer interface func (i *Ingester) v2QueryStream(req *client.QueryRequest, stream client.Ingester_QueryStreamServer) error { + if err := i.checkRunning(); err != nil { + return err + } + spanlog, ctx := spanlogger.New(stream.Context(), "v2QueryStream") defer spanlog.Finish() @@ -1788,6 +1820,10 @@ func (i *Ingester) openExistingTSDB(ctx context.Context) error { // getMemorySeriesMetric returns the total number of in-memory series across all open TSDBs. func (i *Ingester) getMemorySeriesMetric() float64 { + if err := i.checkRunning(); err != nil { + return 0 + } + i.userStatesMtx.RLock() defer i.userStatesMtx.RUnlock() diff --git a/vendor/github.com/cortexproject/cortex/pkg/querier/blocks_store_queryable.go b/vendor/github.com/cortexproject/cortex/pkg/querier/blocks_store_queryable.go index 02c50b5b9d12..69584f01baf4 100644 --- a/vendor/github.com/cortexproject/cortex/pkg/querier/blocks_store_queryable.go +++ b/vendor/github.com/cortexproject/cortex/pkg/querier/blocks_store_queryable.go @@ -136,7 +136,15 @@ type BlocksStoreQueryable struct { subservicesWatcher *services.FailureWatcher } -func NewBlocksStoreQueryable(stores BlocksStoreSet, finder BlocksFinder, consistency *BlocksConsistencyChecker, limits BlocksStoreLimits, queryStoreAfter time.Duration, logger log.Logger, reg prometheus.Registerer) (*BlocksStoreQueryable, error) { +func NewBlocksStoreQueryable( + stores BlocksStoreSet, + finder BlocksFinder, + consistency *BlocksConsistencyChecker, + limits BlocksStoreLimits, + queryStoreAfter time.Duration, + logger log.Logger, + reg prometheus.Registerer, +) (*BlocksStoreQueryable, error) { manager, err := services.NewManager(stores, finder) if err != nil { return nil, errors.Wrap(err, "register blocks storage queryable subservices") @@ -317,20 +325,21 @@ func (q *blocksStoreQuerier) Select(_ bool, sp *storage.SelectHints, matchers .. return q.selectSorted(sp, matchers...) } -func (q *blocksStoreQuerier) LabelNames() ([]string, storage.Warnings, error) { +func (q *blocksStoreQuerier) LabelNames(matchers ...*labels.Matcher) ([]string, storage.Warnings, error) { spanLog, spanCtx := spanlogger.New(q.ctx, "blocksStoreQuerier.LabelNames") defer spanLog.Span.Finish() minT, maxT := q.minT, q.maxT var ( - resMtx sync.Mutex - resNameSets = [][]string{} - resWarnings = storage.Warnings(nil) + resMtx sync.Mutex + resNameSets = [][]string{} + resWarnings = storage.Warnings(nil) + convertedMatchers = convertMatchersToLabelMatcher(matchers) ) queryFunc := func(clients map[BlocksStoreClient][]ulid.ULID, minT, maxT int64) ([]ulid.ULID, error) { - nameSets, warnings, queriedBlocks, err := q.fetchLabelNamesFromStore(spanCtx, clients, minT, maxT) + nameSets, warnings, queriedBlocks, err := q.fetchLabelNamesFromStore(spanCtx, clients, minT, maxT, convertedMatchers) if err != nil { return nil, err } @@ -693,6 +702,7 @@ func (q *blocksStoreQuerier) fetchLabelNamesFromStore( clients map[BlocksStoreClient][]ulid.ULID, minT int64, maxT int64, + matchers []storepb.LabelMatcher, ) ([][]string, storage.Warnings, []ulid.ULID, error) { var ( reqCtx = grpc_metadata.AppendToOutgoingContext(ctx, cortex_tsdb.TenantIDExternalLabel, q.userID) @@ -711,7 +721,7 @@ func (q *blocksStoreQuerier) fetchLabelNamesFromStore( blockIDs := blockIDs g.Go(func() error { - req, err := createLabelNamesRequest(minT, maxT, blockIDs) + req, err := createLabelNamesRequest(minT, maxT, blockIDs, matchers) if err != nil { return errors.Wrapf(err, "failed to create label names request") } @@ -870,10 +880,11 @@ func createSeriesRequest(minT, maxT int64, matchers []storepb.LabelMatcher, skip }, nil } -func createLabelNamesRequest(minT, maxT int64, blockIDs []ulid.ULID) (*storepb.LabelNamesRequest, error) { +func createLabelNamesRequest(minT, maxT int64, blockIDs []ulid.ULID, matchers []storepb.LabelMatcher) (*storepb.LabelNamesRequest, error) { req := &storepb.LabelNamesRequest{ - Start: minT, - End: maxT, + Start: minT, + End: maxT, + Matchers: matchers, } // Selectively query only specific blocks. diff --git a/vendor/github.com/cortexproject/cortex/pkg/querier/chunk_store_queryable.go b/vendor/github.com/cortexproject/cortex/pkg/querier/chunk_store_queryable.go index 6707598e1aef..ba3232158722 100644 --- a/vendor/github.com/cortexproject/cortex/pkg/querier/chunk_store_queryable.go +++ b/vendor/github.com/cortexproject/cortex/pkg/querier/chunk_store_queryable.go @@ -85,7 +85,7 @@ func (q *chunkStoreQuerier) LabelValues(name string, labels ...*labels.Matcher) return nil, nil, nil } -func (q *chunkStoreQuerier) LabelNames() ([]string, storage.Warnings, error) { +func (q *chunkStoreQuerier) LabelNames(matchers ...*labels.Matcher) ([]string, storage.Warnings, error) { return nil, nil, nil } diff --git a/vendor/github.com/cortexproject/cortex/pkg/querier/distributor_queryable.go b/vendor/github.com/cortexproject/cortex/pkg/querier/distributor_queryable.go index 6b13b0a95d02..e93bf85acd1f 100644 --- a/vendor/github.com/cortexproject/cortex/pkg/querier/distributor_queryable.go +++ b/vendor/github.com/cortexproject/cortex/pkg/querier/distributor_queryable.go @@ -192,11 +192,44 @@ func (q *distributorQuerier) LabelValues(name string, matchers ...*labels.Matche return lvs, nil, err } -func (q *distributorQuerier) LabelNames() ([]string, storage.Warnings, error) { - ln, err := q.distributor.LabelNames(q.ctx, model.Time(q.mint), model.Time(q.maxt)) +func (q *distributorQuerier) LabelNames(matchers ...*labels.Matcher) ([]string, storage.Warnings, error) { + if len(matchers) > 0 { + return q.labelNamesWithMatchers(matchers...) + } + + log, ctx := spanlogger.New(q.ctx, "distributorQuerier.LabelNames") + defer log.Span.Finish() + + ln, err := q.distributor.LabelNames(ctx, model.Time(q.mint), model.Time(q.maxt)) return ln, nil, err } +// labelNamesWithMatchers performs the LabelNames call by calling ingester's MetricsForLabelMatchers method +func (q *distributorQuerier) labelNamesWithMatchers(matchers ...*labels.Matcher) ([]string, storage.Warnings, error) { + log, ctx := spanlogger.New(q.ctx, "distributorQuerier.labelNamesWithMatchers") + defer log.Span.Finish() + + ms, err := q.distributor.MetricsForLabelMatchers(ctx, model.Time(q.mint), model.Time(q.maxt), matchers...) + if err != nil { + return nil, nil, err + } + namesMap := make(map[string]struct{}) + + for _, m := range ms { + for name := range m.Metric { + namesMap[string(name)] = struct{}{} + } + } + + names := make([]string, 0, len(namesMap)) + for name := range namesMap { + names = append(names, name) + } + sort.Strings(names) + + return names, nil, nil +} + func (q *distributorQuerier) Close() error { return nil } diff --git a/vendor/github.com/cortexproject/cortex/pkg/querier/error_translate_queryable.go b/vendor/github.com/cortexproject/cortex/pkg/querier/error_translate_queryable.go index ce9289b18bb4..1225690c12bc 100644 --- a/vendor/github.com/cortexproject/cortex/pkg/querier/error_translate_queryable.go +++ b/vendor/github.com/cortexproject/cortex/pkg/querier/error_translate_queryable.go @@ -125,8 +125,8 @@ func (e errorTranslateQuerier) LabelValues(name string, matchers ...*labels.Matc return values, warnings, e.fn(err) } -func (e errorTranslateQuerier) LabelNames() ([]string, storage.Warnings, error) { - values, warnings, err := e.q.LabelNames() +func (e errorTranslateQuerier) LabelNames(matchers ...*labels.Matcher) ([]string, storage.Warnings, error) { + values, warnings, err := e.q.LabelNames(matchers...) return values, warnings, e.fn(err) } @@ -149,8 +149,8 @@ func (e errorTranslateChunkQuerier) LabelValues(name string, matchers ...*labels return values, warnings, e.fn(err) } -func (e errorTranslateChunkQuerier) LabelNames() ([]string, storage.Warnings, error) { - values, warnings, err := e.q.LabelNames() +func (e errorTranslateChunkQuerier) LabelNames(matchers ...*labels.Matcher) ([]string, storage.Warnings, error) { + values, warnings, err := e.q.LabelNames(matchers...) return values, warnings, e.fn(err) } diff --git a/vendor/github.com/cortexproject/cortex/pkg/querier/lazyquery/lazyquery.go b/vendor/github.com/cortexproject/cortex/pkg/querier/lazyquery/lazyquery.go index da96049fddf1..1ca6f4c2b5eb 100644 --- a/vendor/github.com/cortexproject/cortex/pkg/querier/lazyquery/lazyquery.go +++ b/vendor/github.com/cortexproject/cortex/pkg/querier/lazyquery/lazyquery.go @@ -63,8 +63,8 @@ func (l LazyQuerier) LabelValues(name string, matchers ...*labels.Matcher) ([]st } // LabelNames implements Storage.Querier -func (l LazyQuerier) LabelNames() ([]string, storage.Warnings, error) { - return l.next.LabelNames() +func (l LazyQuerier) LabelNames(matchers ...*labels.Matcher) ([]string, storage.Warnings, error) { + return l.next.LabelNames(matchers...) } // Close implements Storage.Querier diff --git a/vendor/github.com/cortexproject/cortex/pkg/querier/querier.go b/vendor/github.com/cortexproject/cortex/pkg/querier/querier.go index cb3b35f32e05..dc62f6b18d7f 100644 --- a/vendor/github.com/cortexproject/cortex/pkg/querier/querier.go +++ b/vendor/github.com/cortexproject/cortex/pkg/querier/querier.go @@ -431,13 +431,13 @@ func (q querier) LabelValues(name string, matchers ...*labels.Matcher) ([]string return strutil.MergeSlices(sets...), warnings, nil } -func (q querier) LabelNames() ([]string, storage.Warnings, error) { +func (q querier) LabelNames(matchers ...*labels.Matcher) ([]string, storage.Warnings, error) { if !q.queryStoreForLabels { - return q.metadataQuerier.LabelNames() + return q.metadataQuerier.LabelNames(matchers...) } if len(q.queriers) == 1 { - return q.queriers[0].LabelNames() + return q.queriers[0].LabelNames(matchers...) } var ( @@ -453,7 +453,7 @@ func (q querier) LabelNames() ([]string, storage.Warnings, error) { querier := querier g.Go(func() error { // NB: Names are sorted in Cortex already. - myNames, myWarnings, err := querier.LabelNames() + myNames, myWarnings, err := querier.LabelNames(matchers...) if err != nil { return err } diff --git a/vendor/github.com/cortexproject/cortex/pkg/querier/queryrange/queryable.go b/vendor/github.com/cortexproject/cortex/pkg/querier/queryrange/queryable.go index a9fe27e03826..7da6cb63fd94 100644 --- a/vendor/github.com/cortexproject/cortex/pkg/querier/queryrange/queryable.go +++ b/vendor/github.com/cortexproject/cortex/pkg/querier/queryrange/queryable.go @@ -136,7 +136,7 @@ func (q *ShardedQuerier) LabelValues(name string, matchers ...*labels.Matcher) ( } // LabelNames returns all the unique label names present in the block in sorted order. -func (q *ShardedQuerier) LabelNames() ([]string, storage.Warnings, error) { +func (q *ShardedQuerier) LabelNames(matchers ...*labels.Matcher) ([]string, storage.Warnings, error) { return nil, nil, errors.Errorf("unimplemented") } diff --git a/vendor/github.com/cortexproject/cortex/pkg/querier/queryrange/test_utils.go b/vendor/github.com/cortexproject/cortex/pkg/querier/queryrange/test_utils.go index d6e9b2dff71e..8f87b3f83760 100644 --- a/vendor/github.com/cortexproject/cortex/pkg/querier/queryrange/test_utils.go +++ b/vendor/github.com/cortexproject/cortex/pkg/querier/queryrange/test_utils.go @@ -175,7 +175,7 @@ func (q *MockShardedQueryable) LabelValues(name string, matchers ...*labels.Matc } // LabelNames returns all the unique label names present in the block in sorted order. -func (q *MockShardedQueryable) LabelNames() ([]string, storage.Warnings, error) { +func (q *MockShardedQueryable) LabelNames(matchers ...*labels.Matcher) ([]string, storage.Warnings, error) { return nil, nil, errors.Errorf("unimplemented") } diff --git a/vendor/github.com/cortexproject/cortex/pkg/querier/tenantfederation/merge_queryable.go b/vendor/github.com/cortexproject/cortex/pkg/querier/tenantfederation/merge_queryable.go index fa1f5ce72725..9efba31d1355 100644 --- a/vendor/github.com/cortexproject/cortex/pkg/querier/tenantfederation/merge_queryable.go +++ b/vendor/github.com/cortexproject/cortex/pkg/querier/tenantfederation/merge_queryable.go @@ -166,12 +166,15 @@ func (m *mergeQuerier) LabelValues(name string, matchers ...*labels.Matcher) ([] // LabelNames returns all the unique label names present in the underlying // queriers. It also adds the `idLabelName` and if present in the original // results the original `idLabelName`. -func (m *mergeQuerier) LabelNames() ([]string, storage.Warnings, error) { +func (m *mergeQuerier) LabelNames(matchers ...*labels.Matcher) ([]string, storage.Warnings, error) { log, _ := spanlogger.New(m.ctx, "mergeQuerier.LabelNames") defer log.Span.Finish() - labelNames, warnings, err := m.mergeDistinctStringSlice(func(ctx context.Context, q storage.Querier) ([]string, storage.Warnings, error) { - return q.LabelNames() - }) + + matchedTenants, filteredMatchers := filterValuesByMatchers(m.idLabelName, m.ids, matchers...) + + labelNames, warnings, err := m.mergeDistinctStringSliceWithTenants(func(ctx context.Context, q storage.Querier) ([]string, storage.Warnings, error) { + return q.LabelNames(filteredMatchers...) + }, matchedTenants) if err != nil { return nil, nil, err } @@ -276,12 +279,6 @@ func (m *mergeQuerier) mergeDistinctStringSliceWithTenants(f stringSliceFunc, te return result, warnings, nil } -// mergeDistinctStringSlice aggregates results from all stringSliceFunc calls -// for all queriers, in parallel. -func (m *mergeQuerier) mergeDistinctStringSlice(f stringSliceFunc) ([]string, storage.Warnings, error) { - return m.mergeDistinctStringSliceWithTenants(f, nil) -} - // Close releases the resources of the Querier. func (m *mergeQuerier) Close() error { errs := tsdb_errors.NewMulti() @@ -354,7 +351,7 @@ func (m *mergeQuerier) Select(sortSeries bool, hints *storage.SelectHints, match // are considered and the forwarded matchers do not contain matchers on the // `idLabelName`. func filterValuesByMatchers(idLabelName string, ids []string, matchers ...*labels.Matcher) (matchedIDs map[string]struct{}, unrelatedMatchers []*labels.Matcher) { - // this contains the matchers which are not related to labelName + // this contains the matchers which are not related to idLabelName unrelatedMatchers = make([]*labels.Matcher, 0, len(matchers)) // build map of values to consider for the matchers @@ -364,24 +361,25 @@ func filterValuesByMatchers(idLabelName string, ids []string, matchers ...*label } for _, m := range matchers { - if m.Name != idLabelName { - // check if has the retained label name - if m.Name == retainExistingPrefix+idLabelName { - // rewrite label to the original name, by copying matcher and - // replacing the label name - rewrittenM := *m - rewrittenM.Name = idLabelName - unrelatedMatchers = append(unrelatedMatchers, &rewrittenM) - } else { - unrelatedMatchers = append(unrelatedMatchers, m) + switch m.Name { + // matcher has idLabelName to target a specific tenant(s) + case idLabelName: + for value := range matchedIDs { + if !m.Matches(value) { + delete(matchedIDs, value) + } } - continue - } - for value := range matchedIDs { - if !m.Matches(value) { - delete(matchedIDs, value) - } + // check if has the retained label name + case retainExistingPrefix + idLabelName: + // rewrite label to the original name, by copying matcher and + // replacing the label name + rewrittenM := *m + rewrittenM.Name = idLabelName + unrelatedMatchers = append(unrelatedMatchers, &rewrittenM) + + default: + unrelatedMatchers = append(unrelatedMatchers, m) } } diff --git a/vendor/github.com/prometheus/prometheus/storage/interface.go b/vendor/github.com/prometheus/prometheus/storage/interface.go index 92ad15b8c08a..d3dab0e21e25 100644 --- a/vendor/github.com/prometheus/prometheus/storage/interface.go +++ b/vendor/github.com/prometheus/prometheus/storage/interface.go @@ -113,8 +113,9 @@ type LabelQuerier interface { LabelValues(name string, matchers ...*labels.Matcher) ([]string, Warnings, error) // LabelNames returns all the unique label names present in the block in sorted order. - // TODO(yeya24): support matchers or hints. - LabelNames() ([]string, Warnings, error) + // If matchers are specified the returned result set is reduced + // to label names of metrics matching the matchers. + LabelNames(matchers ...*labels.Matcher) ([]string, Warnings, error) // Close releases the resources of the Querier. Close() error diff --git a/vendor/github.com/prometheus/prometheus/storage/merge.go b/vendor/github.com/prometheus/prometheus/storage/merge.go index 81e45d55de4b..1c08a537f4b3 100644 --- a/vendor/github.com/prometheus/prometheus/storage/merge.go +++ b/vendor/github.com/prometheus/prometheus/storage/merge.go @@ -218,13 +218,13 @@ func mergeStrings(a, b []string) []string { } // LabelNames returns all the unique label names present in all queriers in sorted order. -func (q *mergeGenericQuerier) LabelNames() ([]string, Warnings, error) { +func (q *mergeGenericQuerier) LabelNames(matchers ...*labels.Matcher) ([]string, Warnings, error) { var ( labelNamesMap = make(map[string]struct{}) warnings Warnings ) for _, querier := range q.queriers { - names, wrn, err := querier.LabelNames() + names, wrn, err := querier.LabelNames(matchers...) if wrn != nil { // TODO(bwplotka): We could potentially wrap warnings. warnings = append(warnings, wrn...) diff --git a/vendor/github.com/prometheus/prometheus/storage/noop.go b/vendor/github.com/prometheus/prometheus/storage/noop.go index 3f800e76cec8..c63353b92f91 100644 --- a/vendor/github.com/prometheus/prometheus/storage/noop.go +++ b/vendor/github.com/prometheus/prometheus/storage/noop.go @@ -32,7 +32,7 @@ func (noopQuerier) LabelValues(string, ...*labels.Matcher) ([]string, Warnings, return nil, nil, nil } -func (noopQuerier) LabelNames() ([]string, Warnings, error) { +func (noopQuerier) LabelNames(...*labels.Matcher) ([]string, Warnings, error) { return nil, nil, nil } @@ -55,7 +55,7 @@ func (noopChunkQuerier) LabelValues(string, ...*labels.Matcher) ([]string, Warni return nil, nil, nil } -func (noopChunkQuerier) LabelNames() ([]string, Warnings, error) { +func (noopChunkQuerier) LabelNames(...*labels.Matcher) ([]string, Warnings, error) { return nil, nil, nil } diff --git a/vendor/github.com/prometheus/prometheus/storage/remote/read.go b/vendor/github.com/prometheus/prometheus/storage/remote/read.go index 94eab01cf81e..7f1d749e6399 100644 --- a/vendor/github.com/prometheus/prometheus/storage/remote/read.go +++ b/vendor/github.com/prometheus/prometheus/storage/remote/read.go @@ -212,7 +212,7 @@ func (q *querier) LabelValues(string, ...*labels.Matcher) ([]string, storage.War } // LabelNames implements storage.Querier and is a noop. -func (q *querier) LabelNames() ([]string, storage.Warnings, error) { +func (q *querier) LabelNames(...*labels.Matcher) ([]string, storage.Warnings, error) { // TODO: Implement: https://github.com/prometheus/prometheus/issues/3351 return nil, nil, errors.New("not implemented") } diff --git a/vendor/github.com/prometheus/prometheus/storage/secondary.go b/vendor/github.com/prometheus/prometheus/storage/secondary.go index 2586a77440e5..64a83b5e7c24 100644 --- a/vendor/github.com/prometheus/prometheus/storage/secondary.go +++ b/vendor/github.com/prometheus/prometheus/storage/secondary.go @@ -55,8 +55,8 @@ func (s *secondaryQuerier) LabelValues(name string, matchers ...*labels.Matcher) return vals, w, nil } -func (s *secondaryQuerier) LabelNames() ([]string, Warnings, error) { - names, w, err := s.genericQuerier.LabelNames() +func (s *secondaryQuerier) LabelNames(matchers ...*labels.Matcher) ([]string, Warnings, error) { + names, w, err := s.genericQuerier.LabelNames(matchers...) if err != nil { return nil, append([]error{err}, w...), nil } diff --git a/vendor/github.com/prometheus/prometheus/tsdb/block.go b/vendor/github.com/prometheus/prometheus/tsdb/block.go index 23a075c4f665..42a91ff59300 100644 --- a/vendor/github.com/prometheus/prometheus/tsdb/block.go +++ b/vendor/github.com/prometheus/prometheus/tsdb/block.go @@ -85,13 +85,17 @@ type IndexReader interface { Series(ref uint64, lset *labels.Labels, chks *[]chunks.Meta) error // LabelNames returns all the unique label names present in the index in sorted order. - LabelNames() ([]string, error) + LabelNames(matchers ...*labels.Matcher) ([]string, error) // LabelValueFor returns label value for the given label name in the series referred to by ID. // If the series couldn't be found or the series doesn't have the requested label a // storage.ErrNotFound is returned as error. LabelValueFor(id uint64, label string) (string, error) + // LabelNamesFor returns all the label names for the series referred to by IDs. + // The names returned are sorted. + LabelNamesFor(ids ...uint64) ([]string, error) + // Close releases the underlying resources of the reader. Close() error } @@ -443,7 +447,15 @@ func (r blockIndexReader) LabelValues(name string, matchers ...*labels.Matcher) return st, errors.Wrapf(err, "block: %s", r.b.Meta().ULID) } - return labelValuesWithMatchers(r, name, matchers...) + return labelValuesWithMatchers(r.ir, name, matchers...) +} + +func (r blockIndexReader) LabelNames(matchers ...*labels.Matcher) ([]string, error) { + if len(matchers) == 0 { + return r.b.LabelNames() + } + + return labelNamesWithMatchers(r.ir, matchers...) } func (r blockIndexReader) Postings(name string, values ...string) (index.Postings, error) { @@ -465,10 +477,6 @@ func (r blockIndexReader) Series(ref uint64, lset *labels.Labels, chks *[]chunks return nil } -func (r blockIndexReader) LabelNames() ([]string, error) { - return r.b.LabelNames() -} - func (r blockIndexReader) Close() error { r.b.pendingReaders.Done() return nil @@ -479,6 +487,12 @@ func (r blockIndexReader) LabelValueFor(id uint64, label string) (string, error) return r.ir.LabelValueFor(id, label) } +// LabelNamesFor returns all the label names for the series referred to by IDs. +// The names returned are sorted. +func (r blockIndexReader) LabelNamesFor(ids ...uint64) ([]string, error) { + return r.ir.LabelNamesFor(ids...) +} + type blockTombstoneReader struct { tombstones.Reader b *Block diff --git a/vendor/github.com/prometheus/prometheus/tsdb/head.go b/vendor/github.com/prometheus/prometheus/tsdb/head.go index 2f1896dee600..92ad7b53ccd5 100644 --- a/vendor/github.com/prometheus/prometheus/tsdb/head.go +++ b/vendor/github.com/prometheus/prometheus/tsdb/head.go @@ -2019,18 +2019,21 @@ func (h *headIndexReader) LabelValues(name string, matchers ...*labels.Matcher) // LabelNames returns all the unique label names present in the head // that are within the time range mint to maxt. -func (h *headIndexReader) LabelNames() ([]string, error) { - h.head.symMtx.RLock() +func (h *headIndexReader) LabelNames(matchers ...*labels.Matcher) ([]string, error) { if h.maxt < h.head.MinTime() || h.mint > h.head.MaxTime() { - h.head.symMtx.RUnlock() return []string{}, nil } - labelNames := h.head.postings.LabelNames() - h.head.symMtx.RUnlock() + if len(matchers) == 0 { + h.head.symMtx.RLock() + labelNames := h.head.postings.LabelNames() + h.head.symMtx.RUnlock() + + sort.Strings(labelNames) + return labelNames, nil + } - sort.Strings(labelNames) - return labelNames, nil + return labelNamesWithMatchers(h, matchers...) } // Postings returns the postings list iterator for the label pairs. @@ -2122,6 +2125,27 @@ func (h *headIndexReader) LabelValueFor(id uint64, label string) (string, error) return value, nil } +// LabelNamesFor returns all the label names for the series referred to by IDs. +// The names returned are sorted. +func (h *headIndexReader) LabelNamesFor(ids ...uint64) ([]string, error) { + namesMap := make(map[string]struct{}) + for _, id := range ids { + memSeries := h.head.series.getByID(id) + if memSeries == nil { + return nil, storage.ErrNotFound + } + for _, lbl := range memSeries.lset { + namesMap[lbl.Name] = struct{}{} + } + } + names := make([]string, 0, len(namesMap)) + for name := range namesMap { + names = append(names, name) + } + sort.Strings(names) + return names, nil +} + func (h *Head) getOrCreate(hash uint64, lset labels.Labels) (*memSeries, bool, error) { // Just using `getOrCreateWithID` below would be semantically sufficient, but we'd create // a new series on every sample inserted via Add(), which causes allocations diff --git a/vendor/github.com/prometheus/prometheus/tsdb/index/index.go b/vendor/github.com/prometheus/prometheus/tsdb/index/index.go index a6ade9455ea2..a7b9e57ef400 100644 --- a/vendor/github.com/prometheus/prometheus/tsdb/index/index.go +++ b/vendor/github.com/prometheus/prometheus/tsdb/index/index.go @@ -523,9 +523,15 @@ func (w *Writer) AddSymbol(sym string) error { } func (w *Writer) finishSymbols() error { + symbolTableSize := w.f.pos - w.toc.Symbols - 4 + // The symbol table's part is 4 bytes. So the total symbol table size must be less than or equal to 2^32-1 + if symbolTableSize > 4294967295 { + return errors.Errorf("symbol table size exceeds 4 bytes: %d", symbolTableSize) + } + // Write out the length and symbol count. w.buf1.Reset() - w.buf1.PutBE32int(int(w.f.pos - w.toc.Symbols - 4)) + w.buf1.PutBE32int(int(symbolTableSize)) w.buf1.PutBE32int(int(w.numSymbols)) if err := w.writeAt(w.buf1.Get(), w.toc.Symbols); err != nil { return err @@ -1511,6 +1517,49 @@ func (r *Reader) LabelValues(name string, matchers ...*labels.Matcher) ([]string return values, nil } +// LabelNamesFor returns all the label names for the series referred to by IDs. +// The names returned are sorted. +func (r *Reader) LabelNamesFor(ids ...uint64) ([]string, error) { + // Gather offsetsMap the name offsetsMap in the symbol table first + offsetsMap := make(map[uint32]struct{}) + for _, id := range ids { + offset := id + // In version 2 series IDs are no longer exact references but series are 16-byte padded + // and the ID is the multiple of 16 of the actual position. + if r.version == FormatV2 { + offset = id * 16 + } + + d := encoding.NewDecbufUvarintAt(r.b, int(offset), castagnoliTable) + buf := d.Get() + if d.Err() != nil { + return nil, errors.Wrap(d.Err(), "get buffer for series") + } + + offsets, err := r.dec.LabelNamesOffsetsFor(buf) + if err != nil { + return nil, errors.Wrap(err, "get label name offsets") + } + for _, off := range offsets { + offsetsMap[off] = struct{}{} + } + } + + // Lookup the unique symbols. + names := make([]string, 0, len(offsetsMap)) + for off := range offsetsMap { + name, err := r.lookupSymbol(off) + if err != nil { + return nil, errors.Wrap(err, "lookup symbol in LabelNamesFor") + } + names = append(names, name) + } + + sort.Strings(names) + + return names, nil +} + // LabelValueFor returns label value for the given label name in the series referred to by ID. func (r *Reader) LabelValueFor(id uint64, label string) (string, error) { offset := id @@ -1664,7 +1713,12 @@ func (r *Reader) Size() int64 { } // LabelNames returns all the unique label names present in the index. -func (r *Reader) LabelNames() ([]string, error) { +// TODO(twilkie) implement support for matchers +func (r *Reader) LabelNames(matchers ...*labels.Matcher) ([]string, error) { + if len(matchers) > 0 { + return nil, errors.Errorf("matchers parameter is not implemented: %+v", matchers) + } + labelNames := make([]string, 0, len(r.postings)) for name := range r.postings { if name == allPostingsKey.Name { @@ -1715,6 +1769,25 @@ func (dec *Decoder) Postings(b []byte) (int, Postings, error) { return n, newBigEndianPostings(l), d.Err() } +// LabelNamesOffsetsFor decodes the offsets of the name symbols for a given series. +// They are returned in the same order they're stored, which should be sorted lexicographically. +func (dec *Decoder) LabelNamesOffsetsFor(b []byte) ([]uint32, error) { + d := encoding.Decbuf{B: b} + k := d.Uvarint() + + offsets := make([]uint32, k) + for i := 0; i < k; i++ { + offsets[i] = uint32(d.Uvarint()) + _ = d.Uvarint() // skip the label value + + if d.Err() != nil { + return nil, errors.Wrap(d.Err(), "read series label offsets") + } + } + + return offsets, d.Err() +} + // LabelValueFor decodes a label for a given series. func (dec *Decoder) LabelValueFor(b []byte, label string) (string, error) { d := encoding.Decbuf{B: b} diff --git a/vendor/github.com/prometheus/prometheus/tsdb/querier.go b/vendor/github.com/prometheus/prometheus/tsdb/querier.go index af5007fc18bd..18a1fd20a5f3 100644 --- a/vendor/github.com/prometheus/prometheus/tsdb/querier.go +++ b/vendor/github.com/prometheus/prometheus/tsdb/querier.go @@ -88,8 +88,8 @@ func (q *blockBaseQuerier) LabelValues(name string, matchers ...*labels.Matcher) return res, nil, err } -func (q *blockBaseQuerier) LabelNames() ([]string, storage.Warnings, error) { - res, err := q.index.LabelNames() +func (q *blockBaseQuerier) LabelNames(matchers ...*labels.Matcher) ([]string, storage.Warnings, error) { + res, err := q.index.LabelNames(matchers...) return res, nil, err } @@ -407,6 +407,23 @@ func labelValuesWithMatchers(r IndexReader, name string, matchers ...*labels.Mat return values, nil } +func labelNamesWithMatchers(r IndexReader, matchers ...*labels.Matcher) ([]string, error) { + p, err := PostingsForMatchers(r, matchers...) + if err != nil { + return nil, err + } + + var postings []uint64 + for p.Next() { + postings = append(postings, p.At()) + } + if p.Err() != nil { + return nil, errors.Wrapf(p.Err(), "postings for label names with matchers") + } + + return r.LabelNamesFor(postings...) +} + // blockBaseSeriesSet allows to iterate over all series in the single block. // Iterated series are trimmed with given min and max time as well as tombstones. // See newBlockSeriesSet and newBlockChunkSeriesSet to use it for either sample or chunk iterating. diff --git a/vendor/github.com/prometheus/prometheus/web/api/v1/api.go b/vendor/github.com/prometheus/prometheus/web/api/v1/api.go index 8cbc915b5002..745a28c8d785 100644 --- a/vendor/github.com/prometheus/prometheus/web/api/v1/api.go +++ b/vendor/github.com/prometheus/prometheus/web/api/v1/api.go @@ -559,26 +559,18 @@ func (api *API) labelNames(r *http.Request) apiFuncResult { warnings storage.Warnings ) if len(matcherSets) > 0 { - hints := &storage.SelectHints{ - Start: timestamp.FromTime(start), - End: timestamp.FromTime(end), - Func: "series", // There is no series function, this token is used for lookups that don't need samples. - } - labelNamesSet := make(map[string]struct{}) - // Get all series which match matchers. - for _, mset := range matcherSets { - s := q.Select(false, hints, mset...) - for s.Next() { - series := s.At() - for _, lb := range series.Labels() { - labelNamesSet[lb.Name] = struct{}{} - } - } - warnings = append(warnings, s.Warnings()...) - if err := s.Err(); err != nil { + + for _, matchers := range matcherSets { + vals, callWarnings, err := q.LabelNames(matchers...) + if err != nil { return apiFuncResult{nil, &apiError{errorExec, err}, warnings, nil} } + + warnings = append(warnings, callWarnings...) + for _, val := range vals { + labelNamesSet[val] = struct{}{} + } } // Convert the map to an array. diff --git a/vendor/modules.txt b/vendor/modules.txt index 73a3d678da97..93de398fa144 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -184,7 +184,7 @@ github.com/coreos/go-systemd/sdjournal github.com/coreos/go-systemd/v22/journal # github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f github.com/coreos/pkg/capnslog -# github.com/cortexproject/cortex v1.9.1-0.20210722081137-485474c9afb2 +# github.com/cortexproject/cortex v1.9.1-0.20210726155107-a4bf10354786 ## explicit github.com/cortexproject/cortex/pkg/alertmanager github.com/cortexproject/cortex/pkg/alertmanager/alertmanagerpb @@ -812,7 +812,7 @@ github.com/prometheus/node_exporter/https github.com/prometheus/procfs github.com/prometheus/procfs/internal/fs github.com/prometheus/procfs/internal/util -# github.com/prometheus/prometheus v1.8.2-0.20210720084720-59d02b5ef003 +# github.com/prometheus/prometheus v1.8.2-0.20210720123808-b1ed4a0a663d ## explicit github.com/prometheus/prometheus/config github.com/prometheus/prometheus/discovery