vendor: update cortex (#512)

Signed-off-by: Goutham Veeramachaneni <gouthamve@gmail.com>
pull/514/head
Goutham Veeramachaneni 6 years ago committed by GitHub
parent cfb4c60813
commit e54a1b21c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      Gopkg.lock
  2. 16
      pkg/ingester/flush.go
  3. 8
      pkg/ingester/stream.go
  4. 2
      pkg/logproto/dep.go
  5. 11
      pkg/util/conv.go
  6. 17
      vendor/github.com/cortexproject/cortex/pkg/chunk/chunk_store.go
  7. 3
      vendor/github.com/cortexproject/cortex/pkg/chunk/encoding/bigchunk.go
  8. 8
      vendor/github.com/cortexproject/cortex/pkg/chunk/gcp/bigtable_object_client.go
  9. 44
      vendor/github.com/cortexproject/cortex/pkg/chunk/series_store.go
  10. 2
      vendor/github.com/cortexproject/cortex/pkg/chunk/storage/bytes.go
  11. 15
      vendor/github.com/cortexproject/cortex/pkg/chunk/storage/caching_fixtures.go
  12. 41
      vendor/github.com/cortexproject/cortex/pkg/chunk/storage/caching_index_client.go
  13. 200
      vendor/github.com/cortexproject/cortex/pkg/chunk/storage/caching_index_client.pb.go
  14. 8
      vendor/github.com/cortexproject/cortex/pkg/chunk/storage/caching_index_client.proto
  15. 2
      vendor/github.com/cortexproject/cortex/pkg/chunk/storage/factory.go
  16. 111
      vendor/github.com/cortexproject/cortex/pkg/ingester/client/compat.go
  17. 919
      vendor/github.com/cortexproject/cortex/pkg/ingester/client/cortex.pb.go
  18. 10
      vendor/github.com/cortexproject/cortex/pkg/ingester/client/cortex.proto
  19. 20
      vendor/github.com/cortexproject/cortex/pkg/ingester/client/fnv.go
  20. 187
      vendor/github.com/cortexproject/cortex/pkg/ingester/client/timeseries.go
  21. 25
      vendor/github.com/cortexproject/cortex/pkg/ingester/index/index.go
  22. 209
      vendor/github.com/cortexproject/cortex/pkg/ring/ring.pb.go
  23. 10
      vendor/github.com/cortexproject/cortex/pkg/util/extract/extract.go
  24. 26
      vendor/github.com/cortexproject/cortex/pkg/util/flagext/deprecated.go
  25. 4
      vendor/github.com/cortexproject/cortex/pkg/util/hash_fp.go
  26. 14
      vendor/github.com/cortexproject/cortex/pkg/util/log.go
  27. 12
      vendor/github.com/cortexproject/cortex/pkg/util/validation/limits.go
  28. 26
      vendor/github.com/cortexproject/cortex/pkg/util/validation/override.go
  29. 13
      vendor/github.com/cortexproject/cortex/pkg/util/validation/validate.go

8
Gopkg.lock generated

@ -187,7 +187,7 @@
[[projects]]
branch = "lazy-load-chunks"
digest = "1:ec8e0308d1e557f50317a6437073a7a859d73e4cf8e4c20a60d7009e352353c6"
digest = "1:bf1fa66c54722bc8664f1465e427cd6fe7df52f2b6fd5ab996baf37601687b70"
name = "github.com/cortexproject/cortex"
packages = [
"pkg/chunk",
@ -211,10 +211,9 @@
"pkg/util/middleware",
"pkg/util/spanlogger",
"pkg/util/validation",
"pkg/util/wire",
]
pruneopts = "UT"
revision = "161f6716cba9a32f07f359c4f9f8578e0c5d5ae8"
revision = "95a3f308e95617732b76e337874e83ccf173cf14"
source = "https://github.com/grafana/cortex"
[[projects]]
@ -1367,7 +1366,6 @@
"github.com/cortexproject/cortex/pkg/util",
"github.com/cortexproject/cortex/pkg/util/flagext",
"github.com/cortexproject/cortex/pkg/util/validation",
"github.com/cortexproject/cortex/pkg/util/wire",
"github.com/fatih/color",
"github.com/go-kit/kit/log",
"github.com/go-kit/kit/log/level",
@ -1391,10 +1389,12 @@
"github.com/prometheus/prometheus/discovery/targetgroup",
"github.com/prometheus/prometheus/pkg/labels",
"github.com/prometheus/prometheus/pkg/relabel",
"github.com/prometheus/prometheus/pkg/textparse",
"github.com/prometheus/prometheus/relabel",
"github.com/stretchr/testify/assert",
"github.com/stretchr/testify/require",
"github.com/weaveworks/common/httpgrpc",
"github.com/weaveworks/common/httpgrpc/server",
"github.com/weaveworks/common/middleware",
"github.com/weaveworks/common/server",
"github.com/weaveworks/common/tracing",

@ -184,7 +184,7 @@ func (i *Ingester) flushUserSeries(userID string, fp model.Fingerprint, immediat
return nil
}
func (i *Ingester) collectChunksToFlush(instance *instance, fp model.Fingerprint, immediate bool) ([]*chunkDesc, []client.LabelPair) {
func (i *Ingester) collectChunksToFlush(instance *instance, fp model.Fingerprint, immediate bool) ([]*chunkDesc, []client.LabelAdapter) {
instance.streamsMtx.Lock()
defer instance.streamsMtx.Unlock()
@ -234,18 +234,18 @@ func (i *Ingester) removeFlushedChunks(instance *instance, stream *stream) {
if len(stream.chunks) == 0 {
delete(instance.streams, stream.fp)
instance.index.Delete(client.FromLabelPairsToLabels(stream.labels), stream.fp)
instance.index.Delete(client.FromLabelAdaptersToLabels(stream.labels), stream.fp)
instance.streamsRemovedTotal.Inc()
}
}
func (i *Ingester) flushChunks(ctx context.Context, fp model.Fingerprint, labelPairs []client.LabelPair, cs []*chunkDesc) error {
func (i *Ingester) flushChunks(ctx context.Context, fp model.Fingerprint, labelPairs []client.LabelAdapter, cs []*chunkDesc) error {
userID, err := user.ExtractOrgID(ctx)
if err != nil {
return err
}
metric := fromLabelPairs(labelPairs)
metric := client.FromLabelAdaptersToMetric(labelPairs)
metric[nameLabel] = logsValue
wireChunks := make([]chunk.Chunk, 0, len(cs))
@ -288,11 +288,3 @@ func (i *Ingester) flushChunks(ctx context.Context, fp model.Fingerprint, labelP
return nil
}
func fromLabelPairs(ls []client.LabelPair) model.Metric {
m := make(model.Metric, len(ls))
for _, l := range ls {
m[model.LabelName(l.Name)] = model.LabelValue(l.Value)
}
return m
}

@ -47,7 +47,7 @@ type stream struct {
// Not thread-safe; assume accesses to this are locked by caller.
chunks []chunkDesc
fp model.Fingerprint
labels []client.LabelPair
labels []client.LabelAdapter
}
type chunkDesc struct {
@ -58,7 +58,7 @@ type chunkDesc struct {
lastUpdated time.Time
}
func newStream(fp model.Fingerprint, labels []client.LabelPair) *stream {
func newStream(fp model.Fingerprint, labels []client.LabelAdapter) *stream {
return &stream{
fp: fp,
labels: labels,
@ -96,7 +96,7 @@ func (s *stream) Push(_ context.Context, entries []logproto.Entry) error {
}
if appendErr == chunkenc.ErrOutOfOrder {
return httpgrpc.Errorf(http.StatusBadRequest, "entry out of order for stream: %s", client.FromLabelPairsToLabels(s.labels).String())
return httpgrpc.Errorf(http.StatusBadRequest, "entry out of order for stream: %s", client.FromLabelAdaptersToLabels(s.labels).String())
}
return appendErr
@ -121,5 +121,5 @@ func (s *stream) Iterator(from, through time.Time, direction logproto.Direction)
}
}
return iter.NewNonOverlappingIterator(iterators, client.FromLabelPairsToLabels(s.labels).String()), nil
return iter.NewNonOverlappingIterator(iterators, client.FromLabelAdaptersToLabels(s.labels).String()), nil
}

@ -2,6 +2,6 @@ package logproto
import (
// trick dep into including this, needed by the generated code.
_ "github.com/cortexproject/cortex/pkg/util/wire"
_ "github.com/cortexproject/cortex/pkg/chunk/storage"
_ "github.com/gogo/protobuf/types"
)

@ -2,22 +2,21 @@ package util
import (
"github.com/cortexproject/cortex/pkg/ingester/client"
"github.com/cortexproject/cortex/pkg/util/wire"
"github.com/grafana/loki/pkg/parser"
)
// ToClientLabels parses the labels and converts them to the Cortex type.
func ToClientLabels(labels string) ([]client.LabelPair, error) {
func ToClientLabels(labels string) ([]client.LabelAdapter, error) {
ls, err := parser.Labels(labels)
if err != nil {
return nil, err
}
pairs := make([]client.LabelPair, 0, len(ls))
pairs := make([]client.LabelAdapter, 0, len(ls))
for i := 0; i < len(ls); i++ {
pairs = append(pairs, client.LabelPair{
Name: wire.Bytes(ls[i].Name),
Value: wire.Bytes(ls[i].Value),
pairs = append(pairs, client.LabelAdapter{
Name: ls[i].Name,
Value: ls[i].Value,
})
}
return pairs, nil

@ -20,6 +20,7 @@ import (
"github.com/cortexproject/cortex/pkg/chunk/cache"
"github.com/cortexproject/cortex/pkg/util"
"github.com/cortexproject/cortex/pkg/util/extract"
"github.com/cortexproject/cortex/pkg/util/flagext"
"github.com/cortexproject/cortex/pkg/util/spanlogger"
"github.com/cortexproject/cortex/pkg/util/validation"
"github.com/weaveworks/common/httpgrpc"
@ -58,25 +59,21 @@ type StoreConfig struct {
ChunkCacheConfig cache.Config
WriteDedupeCacheConfig cache.Config
MinChunkAge time.Duration
CardinalityCacheSize int
CardinalityCacheValidity time.Duration
CardinalityLimit int
MinChunkAge time.Duration
CacheLookupsOlderThan time.Duration
}
// RegisterFlags adds the flags required to config this to the given FlagSet
func (cfg *StoreConfig) RegisterFlags(f *flag.FlagSet) {
cfg.ChunkCacheConfig.RegisterFlagsWithPrefix("", "Cache config for chunks. ", f)
cfg.WriteDedupeCacheConfig.RegisterFlagsWithPrefix("store.index-cache-write.", "Cache config for index entry writing. ", f)
f.DurationVar(&cfg.MinChunkAge, "store.min-chunk-age", 0, "Minimum time between chunk update and being saved to the store.")
f.IntVar(&cfg.CardinalityCacheSize, "store.cardinality-cache-size", 0, "Size of in-memory cardinality cache, 0 to disable.")
f.DurationVar(&cfg.CardinalityCacheValidity, "store.cardinality-cache-validity", 1*time.Hour, "Period for which entries in the cardinality cache are valid.")
f.IntVar(&cfg.CardinalityLimit, "store.cardinality-limit", 1e5, "Cardinality limit for index queries.")
f.DurationVar(&cfg.CacheLookupsOlderThan, "store.cache-lookups-older-than", 0, "Cache index entries older than this period. 0 to disable.")
// Deprecated.
flagext.DeprecatedFlag(f, "store.cardinality-cache-size", "DEPRECATED. Use store.index-cache-size.enable-fifocache and store.cardinality-cache.fifocache.size instead.")
flagext.DeprecatedFlag(f, "store.cardinality-cache-validity", "DEPRECATED. Use store.index-cache-size.enable-fifocache and store.cardinality-cache.fifocache.duration instead.")
}
// store implements Store
@ -211,7 +208,7 @@ func (c *store) validateQuery(ctx context.Context, from model.Time, through *mod
maxQueryLength := c.limits.MaxQueryLength(userID)
if maxQueryLength > 0 && (*through).Sub(from) > maxQueryLength {
return "", nil, false, httpgrpc.Errorf(http.StatusBadRequest, "invalid query, length > limit (%s > %s)", (*through).Sub(from), maxQueryLength)
return "", nil, false, httpgrpc.Errorf(http.StatusBadRequest, validation.ErrQueryTooLong, (*through).Sub(from), maxQueryLength)
}
now := model.Now()

@ -161,8 +161,9 @@ func (b *bigchunk) Len() int {
}
func (b *bigchunk) Size() int {
sum := 0
sum := 2 // For the number of sub chunks.
for _, c := range b.chunks {
sum += 2 // For the length of the sub chunk.
sum += len(c.Bytes())
}
return sum

@ -114,7 +114,7 @@ func (s *bigtableObjectClient) GetChunks(ctx context.Context, input []chunk.Chun
decodeContext := chunk.NewDecodeContext()
var processingErr error
var recievedChunks = 0
var receivedChunks = 0
// rows are returned in key order, not order in row list
err := table.ReadRows(ctx, page, func(row bigtable.Row) bool {
@ -130,7 +130,7 @@ func (s *bigtableObjectClient) GetChunks(ctx context.Context, input []chunk.Chun
return false
}
recievedChunks++
receivedChunks++
outs <- chunk
return true
})
@ -139,8 +139,8 @@ func (s *bigtableObjectClient) GetChunks(ctx context.Context, input []chunk.Chun
errs <- processingErr
} else if err != nil {
errs <- errors.WithStack(err)
} else if recievedChunks < len(page) {
errs <- errors.WithStack(fmt.Errorf("Asked for %d chunks for Bigtable, received %d", len(page), recievedChunks))
} else if receivedChunks < len(page) {
errs <- errors.WithStack(fmt.Errorf("Asked for %d chunks for Bigtable, received %d", len(page), receivedChunks))
}
}(page)
}

@ -23,7 +23,9 @@ import (
)
var (
errCardinalityExceeded = errors.New("cardinality limit exceeded")
// ErrCardinalityExceeded is returned when the user reads a row that
// is too large.
ErrCardinalityExceeded = errors.New("cardinality limit exceeded")
indexLookupsPerQuery = promauto.NewHistogram(prometheus.HistogramOpts{
Namespace: "cortex",
@ -57,8 +59,6 @@ var (
// seriesStore implements Store
type seriesStore struct {
store
cardinalityCache *cache.FifoCache
writeDedupeCache cache.Cache
}
@ -89,10 +89,6 @@ func newSeriesStore(cfg StoreConfig, schema Schema, index IndexClient, chunks Ob
limits: limits,
Fetcher: fetcher,
},
cardinalityCache: cache.NewFifoCache("cardinality", cache.FifoCacheConfig{
Size: cfg.CardinalityCacheSize,
Validity: cfg.CardinalityCacheValidity,
}),
writeDedupeCache: writeDedupeCache,
}, nil
}
@ -229,15 +225,21 @@ func (c *seriesStore) lookupSeriesByMetricNameMatchers(ctx context.Context, from
ids = intersectStrings(ids, incoming)
}
case err := <-incomingErrors:
if err == errCardinalityExceeded {
// The idea is that if we have 2 matchers, and if one returns a lot of
// series and the other returns only 10 (a few), we don't lookup the first one at all.
// We just manually filter through the 10 series again using "filterChunksByMatchers",
// saving us from looking up and intersecting a lot of series.
if err == ErrCardinalityExceeded {
cardinalityExceededErrors++
} else {
lastErr = err
}
}
}
// But if every single matcher returns a lot of series, then it makes sense to abort the query.
if cardinalityExceededErrors == len(matchers) {
return nil, errCardinalityExceeded
return nil, ErrCardinalityExceeded
} else if lastErr != nil {
return nil, lastErr
}
@ -270,36 +272,12 @@ func (c *seriesStore) lookupSeriesByMetricNameMatcher(ctx context.Context, from,
}
level.Debug(log).Log("queries", len(queries))
for _, query := range queries {
value, ok := c.cardinalityCache.Get(ctx, query.HashValue)
if !ok {
continue
}
cardinality := value.(int)
if cardinality > c.cfg.CardinalityLimit {
return nil, errCardinalityExceeded
}
}
entries, err := c.lookupEntriesByQueries(ctx, queries)
if err != nil {
return nil, err
}
level.Debug(log).Log("entries", len(entries))
// TODO This is not correct, will overcount for queries > 24hrs
keys := make([]string, 0, len(queries))
values := make([]interface{}, 0, len(queries))
for _, query := range queries {
keys = append(keys, query.HashValue)
values = append(values, len(entries))
}
c.cardinalityCache.Put(ctx, keys, values)
if len(entries) > c.cfg.CardinalityLimit {
return nil, errCardinalityExceeded
}
ids, err := c.parseIndexEntries(ctx, entries, matcher)
if err != nil {
return nil, err

@ -3,6 +3,9 @@ package storage
import (
"time"
"github.com/cortexproject/cortex/pkg/util/flagext"
"github.com/cortexproject/cortex/pkg/util/validation"
"github.com/cortexproject/cortex/pkg/chunk/cache"
"github.com/cortexproject/cortex/pkg/chunk/gcp"
@ -16,11 +19,15 @@ type fixture struct {
func (f fixture) Name() string { return "caching-store" }
func (f fixture) Clients() (chunk.IndexClient, chunk.ObjectClient, chunk.TableClient, chunk.SchemaConfig, error) {
limits, err := defaultLimits()
if err != nil {
return nil, nil, nil, chunk.SchemaConfig{}, err
}
indexClient, objectClient, tableClient, schemaConfig, err := f.fixture.Clients()
indexClient = newCachingIndexClient(indexClient, cache.NewFifoCache("index-fifo", cache.FifoCacheConfig{
Size: 500,
Validity: 5 * time.Minute,
}), 5*time.Minute)
}), 5*time.Minute, limits)
return indexClient, objectClient, tableClient, schemaConfig, err
}
func (f fixture) Teardown() error { return f.fixture.Teardown() }
@ -29,3 +36,9 @@ func (f fixture) Teardown() error { return f.fixture.Teardown() }
var Fixtures = []testutils.Fixture{
fixture{gcp.Fixtures[0]},
}
func defaultLimits() (*validation.Overrides, error) {
var defaults validation.Limits
flagext.DefaultValues(&defaults)
return validation.NewOverrides(defaults)
}

@ -5,15 +5,18 @@ import (
"sync"
"time"
"github.com/go-kit/kit/log/level"
proto "github.com/golang/protobuf/proto"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/weaveworks/common/user"
"github.com/cortexproject/cortex/pkg/chunk"
"github.com/cortexproject/cortex/pkg/chunk/cache"
chunk_util "github.com/cortexproject/cortex/pkg/chunk/util"
"github.com/cortexproject/cortex/pkg/util"
"github.com/cortexproject/cortex/pkg/util/spanlogger"
"github.com/go-kit/kit/log/level"
proto "github.com/golang/protobuf/proto"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/cortexproject/cortex/pkg/util/validation"
)
var (
@ -43,9 +46,10 @@ type cachingIndexClient struct {
chunk.IndexClient
cache cache.Cache
validity time.Duration
limits *validation.Overrides
}
func newCachingIndexClient(client chunk.IndexClient, c cache.Cache, validity time.Duration) chunk.IndexClient {
func newCachingIndexClient(client chunk.IndexClient, c cache.Cache, validity time.Duration, limits *validation.Overrides) chunk.IndexClient {
if c == nil {
return client
}
@ -54,6 +58,7 @@ func newCachingIndexClient(client chunk.IndexClient, c cache.Cache, validity tim
IndexClient: client,
cache: cache.NewSnappy(c),
validity: validity,
limits: limits,
}
}
@ -65,6 +70,12 @@ func (s *cachingIndexClient) QueryPages(ctx context.Context, queries []chunk.Ind
// We cache the entire row, so filter client side.
callback = chunk_util.QueryFilter(callback)
userID, err := user.ExtractOrgID(ctx)
if err != nil {
return err
}
cardinalityLimit := int32(s.limits.CardinalityLimit(userID))
// Build list of keys to lookup in the cache.
keys := make([]string, 0, len(queries))
queriesByKey := make(map[string][]chunk.IndexQuery, len(queries))
@ -76,6 +87,10 @@ func (s *cachingIndexClient) QueryPages(ctx context.Context, queries []chunk.Ind
batches, misses := s.cacheFetch(ctx, keys)
for _, batch := range batches {
if cardinalityLimit > 0 && batch.Cardinality > cardinalityLimit {
return chunk.ErrCardinalityExceeded
}
queries := queriesByKey[batch.Key]
for _, query := range queries {
callback(query, batch)
@ -115,7 +130,7 @@ func (s *cachingIndexClient) QueryPages(ctx context.Context, queries []chunk.Ind
results[key] = rb
}
err := s.IndexClient.QueryPages(ctx, cacheableMissed, func(cacheableQuery chunk.IndexQuery, r chunk.ReadBatch) bool {
err = s.IndexClient.QueryPages(ctx, cacheableMissed, func(cacheableQuery chunk.IndexQuery, r chunk.ReadBatch) bool {
resultsMtx.Lock()
defer resultsMtx.Unlock()
key := queryKey(cacheableQuery)
@ -135,9 +150,20 @@ func (s *cachingIndexClient) QueryPages(ctx context.Context, queries []chunk.Ind
defer resultsMtx.Unlock()
keys := make([]string, 0, len(results))
batches := make([]ReadBatch, 0, len(results))
var cardinalityErr error
for key, batch := range results {
cardinality := int32(len(batch.Entries))
if cardinalityLimit > 0 && cardinality > cardinalityLimit {
batch.Cardinality = cardinality
batch.Entries = nil
cardinalityErr = chunk.ErrCardinalityExceeded
}
keys = append(keys, key)
batches = append(batches, batch)
if cardinalityErr != nil {
continue
}
queries := queriesByKey[key]
for _, query := range queries {
@ -145,8 +171,8 @@ func (s *cachingIndexClient) QueryPages(ctx context.Context, queries []chunk.Ind
}
}
s.cacheStore(ctx, keys, batches)
return cardinalityErr
}
return nil
}
// Iterator implements chunk.ReadBatch.
@ -250,7 +276,6 @@ func (s *cachingIndexClient) cacheFetch(ctx context.Context, keys []string) (bat
}
if readBatch.Expiry != 0 && time.Now().After(time.Unix(0, readBatch.Expiry)) {
level.Debug(log).Log("msg", "dropping index cache entry due to expiration", "key", key, "readBatch.Key", readBatch.Key, "expiry", time.Unix(0, readBatch.Expiry))
continue
}

@ -3,17 +3,15 @@
package storage
import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
import _ "github.com/gogo/protobuf/gogoproto"
import github_com_cortexproject_cortex_pkg_util_wire "github.com/cortexproject/cortex/pkg/util/wire"
import strings "strings"
import reflect "reflect"
import io "io"
import (
fmt "fmt"
_ "github.com/gogo/protobuf/gogoproto"
proto "github.com/gogo/protobuf/proto"
io "io"
math "math"
reflect "reflect"
strings "strings"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
@ -27,14 +25,14 @@ var _ = math.Inf
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
type Entry struct {
Column github_com_cortexproject_cortex_pkg_util_wire.Bytes `protobuf:"bytes,1,opt,name=Column,json=column,proto3,customtype=github.com/cortexproject/cortex/pkg/util/wire.Bytes" json:"Column"`
Value github_com_cortexproject_cortex_pkg_util_wire.Bytes `protobuf:"bytes,2,opt,name=Value,json=value,proto3,customtype=github.com/cortexproject/cortex/pkg/util/wire.Bytes" json:"Value"`
Column Bytes `protobuf:"bytes,1,opt,name=Column,json=column,proto3,customtype=Bytes" json:"Column"`
Value Bytes `protobuf:"bytes,2,opt,name=Value,json=value,proto3,customtype=Bytes" json:"Value"`
}
func (m *Entry) Reset() { *m = Entry{} }
func (*Entry) ProtoMessage() {}
func (*Entry) Descriptor() ([]byte, []int) {
return fileDescriptor_caching_index_client_2f4bf220288f700f, []int{0}
return fileDescriptor_a60039d4a2d816f6, []int{0}
}
func (m *Entry) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -51,8 +49,8 @@ func (m *Entry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return b[:n], nil
}
}
func (dst *Entry) XXX_Merge(src proto.Message) {
xxx_messageInfo_Entry.Merge(dst, src)
func (m *Entry) XXX_Merge(src proto.Message) {
xxx_messageInfo_Entry.Merge(m, src)
}
func (m *Entry) XXX_Size() int {
return m.Size()
@ -64,16 +62,19 @@ func (m *Entry) XXX_DiscardUnknown() {
var xxx_messageInfo_Entry proto.InternalMessageInfo
type ReadBatch struct {
Entries []Entry `protobuf:"bytes,1,rep,name=entries" json:"entries"`
Entries []Entry `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries"`
Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"`
// The time at which the key expires.
Expiry int64 `protobuf:"varint,3,opt,name=expiry,proto3" json:"expiry,omitempty"`
// The number of entries; used for cardinality limiting.
// entries will be empty when this is set.
Cardinality int32 `protobuf:"varint,4,opt,name=cardinality,proto3" json:"cardinality,omitempty"`
}
func (m *ReadBatch) Reset() { *m = ReadBatch{} }
func (*ReadBatch) ProtoMessage() {}
func (*ReadBatch) Descriptor() ([]byte, []int) {
return fileDescriptor_caching_index_client_2f4bf220288f700f, []int{1}
return fileDescriptor_a60039d4a2d816f6, []int{1}
}
func (m *ReadBatch) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -90,8 +91,8 @@ func (m *ReadBatch) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return b[:n], nil
}
}
func (dst *ReadBatch) XXX_Merge(src proto.Message) {
xxx_messageInfo_ReadBatch.Merge(dst, src)
func (m *ReadBatch) XXX_Merge(src proto.Message) {
xxx_messageInfo_ReadBatch.Merge(m, src)
}
func (m *ReadBatch) XXX_Size() int {
return m.Size()
@ -123,10 +124,47 @@ func (m *ReadBatch) GetExpiry() int64 {
return 0
}
func (m *ReadBatch) GetCardinality() int32 {
if m != nil {
return m.Cardinality
}
return 0
}
func init() {
proto.RegisterType((*Entry)(nil), "storage.Entry")
proto.RegisterType((*ReadBatch)(nil), "storage.ReadBatch")
}
func init() {
proto.RegisterFile("github.com/cortexproject/cortex/pkg/chunk/storage/caching_index_client.proto", fileDescriptor_a60039d4a2d816f6)
}
var fileDescriptor_a60039d4a2d816f6 = []byte{
// 335 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0xb1, 0x4e, 0xc3, 0x30,
0x00, 0x44, 0x63, 0xd2, 0xa4, 0xaa, 0x0b, 0x08, 0x65, 0x40, 0x11, 0x83, 0x1b, 0x15, 0x21, 0x65,
0x21, 0x91, 0x80, 0x2f, 0x08, 0x62, 0x63, 0x0a, 0x12, 0x6b, 0xe5, 0xba, 0x26, 0x31, 0x4d, 0xed,
0xc8, 0x75, 0x50, 0xb3, 0xb1, 0xb1, 0xf2, 0x19, 0x7c, 0x4a, 0xc7, 0x8e, 0x15, 0x43, 0x45, 0xdd,
0x85, 0xb1, 0x9f, 0x80, 0x6a, 0x82, 0xd4, 0x81, 0xed, 0x9e, 0xef, 0x7c, 0x67, 0x19, 0xde, 0x67,
0x4c, 0xe5, 0xd5, 0x30, 0x22, 0x62, 0x12, 0x13, 0x21, 0x15, 0x9d, 0x95, 0x52, 0x3c, 0x53, 0xa2,
0x1a, 0x8a, 0xcb, 0x71, 0x16, 0x93, 0xbc, 0xe2, 0xe3, 0x78, 0xaa, 0x84, 0xc4, 0x19, 0x8d, 0x09,
0x26, 0x39, 0xe3, 0xd9, 0x80, 0xf1, 0x11, 0x9d, 0x0d, 0x48, 0xc1, 0x28, 0x57, 0x51, 0x29, 0x85,
0x12, 0x5e, 0xbb, 0xc9, 0x9c, 0x5d, 0xee, 0xd5, 0x66, 0x22, 0x13, 0xb1, 0xf1, 0x87, 0xd5, 0x93,
0x21, 0x03, 0x46, 0xfd, 0xde, 0xeb, 0x3f, 0x40, 0xe7, 0x8e, 0x2b, 0x59, 0x7b, 0x17, 0xd0, 0xbd,
0x15, 0x45, 0x35, 0xe1, 0x3e, 0x08, 0x40, 0x78, 0x98, 0x1c, 0xcd, 0x57, 0x3d, 0xeb, 0x73, 0xd5,
0x73, 0x92, 0x5a, 0xd1, 0x69, 0xea, 0x12, 0x63, 0x7a, 0xe7, 0xd0, 0x79, 0xc4, 0x45, 0x45, 0xfd,
0x83, 0xff, 0x52, 0xce, 0xcb, 0xce, 0xeb, 0xbf, 0x01, 0xd8, 0x49, 0x29, 0x1e, 0x25, 0x58, 0x91,
0xdc, 0x8b, 0x60, 0x9b, 0x72, 0x25, 0x19, 0x9d, 0xfa, 0x20, 0xb0, 0xc3, 0xee, 0xd5, 0x71, 0xd4,
0x3c, 0x36, 0x32, 0xd3, 0x49, 0x6b, 0x57, 0x92, 0xfe, 0x85, 0xbc, 0x13, 0x68, 0x8f, 0x69, 0x6d,
0x06, 0x3a, 0xe9, 0x4e, 0x7a, 0xa7, 0xd0, 0xa5, 0xb3, 0x92, 0xc9, 0xda, 0xb7, 0x03, 0x10, 0xda,
0x69, 0x43, 0x5e, 0x00, 0xbb, 0x04, 0xcb, 0x11, 0xe3, 0xb8, 0x60, 0xaa, 0xf6, 0x5b, 0x01, 0x08,
0x9d, 0x74, 0xff, 0x28, 0xb9, 0x59, 0xac, 0x91, 0xb5, 0x5c, 0x23, 0x6b, 0xbb, 0x46, 0xe0, 0x55,
0x23, 0xf0, 0xa1, 0x11, 0x98, 0x6b, 0x04, 0x16, 0x1a, 0x81, 0x2f, 0x8d, 0xc0, 0xb7, 0x46, 0xd6,
0x56, 0x23, 0xf0, 0xbe, 0x41, 0xd6, 0x62, 0x83, 0xac, 0xe5, 0x06, 0x59, 0x43, 0xd7, 0xfc, 0xcd,
0xf5, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x4b, 0xd2, 0x5d, 0xd9, 0xa3, 0x01, 0x00, 0x00,
}
func (this *Entry) Equal(that interface{}) bool {
if that == nil {
return this == nil
@ -187,6 +225,9 @@ func (this *ReadBatch) Equal(that interface{}) bool {
if this.Expiry != that1.Expiry {
return false
}
if this.Cardinality != that1.Cardinality {
return false
}
return true
}
func (this *Entry) GoString() string {
@ -204,7 +245,7 @@ func (this *ReadBatch) GoString() string {
if this == nil {
return "nil"
}
s := make([]string, 0, 7)
s := make([]string, 0, 8)
s = append(s, "&storage.ReadBatch{")
if this.Entries != nil {
vs := make([]*Entry, len(this.Entries))
@ -215,6 +256,7 @@ func (this *ReadBatch) GoString() string {
}
s = append(s, "Key: "+fmt.Sprintf("%#v", this.Key)+",\n")
s = append(s, "Expiry: "+fmt.Sprintf("%#v", this.Expiry)+",\n")
s = append(s, "Cardinality: "+fmt.Sprintf("%#v", this.Cardinality)+",\n")
s = append(s, "}")
return strings.Join(s, "")
}
@ -244,17 +286,17 @@ func (m *Entry) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0xa
i++
i = encodeVarintCachingIndexClient(dAtA, i, uint64(m.Column.Size()))
n1, err := m.Column.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
n1, err1 := m.Column.MarshalTo(dAtA[i:])
if err1 != nil {
return 0, err1
}
i += n1
dAtA[i] = 0x12
i++
i = encodeVarintCachingIndexClient(dAtA, i, uint64(m.Value.Size()))
n2, err := m.Value.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
n2, err2 := m.Value.MarshalTo(dAtA[i:])
if err2 != nil {
return 0, err2
}
i += n2
return i, nil
@ -298,6 +340,11 @@ func (m *ReadBatch) MarshalTo(dAtA []byte) (int, error) {
i++
i = encodeVarintCachingIndexClient(dAtA, i, uint64(m.Expiry))
}
if m.Cardinality != 0 {
dAtA[i] = 0x20
i++
i = encodeVarintCachingIndexClient(dAtA, i, uint64(m.Cardinality))
}
return i, nil
}
@ -342,6 +389,9 @@ func (m *ReadBatch) Size() (n int) {
if m.Expiry != 0 {
n += 1 + sovCachingIndexClient(uint64(m.Expiry))
}
if m.Cardinality != 0 {
n += 1 + sovCachingIndexClient(uint64(m.Cardinality))
}
return n
}
@ -373,10 +423,16 @@ func (this *ReadBatch) String() string {
if this == nil {
return "nil"
}
repeatedStringForEntries := "[]Entry{"
for _, f := range this.Entries {
repeatedStringForEntries += strings.Replace(strings.Replace(f.String(), "Entry", "Entry", 1), `&`, ``, 1) + ","
}
repeatedStringForEntries += "}"
s := strings.Join([]string{`&ReadBatch{`,
`Entries:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Entries), "Entry", "Entry", 1), `&`, ``, 1) + `,`,
`Entries:` + repeatedStringForEntries + `,`,
`Key:` + fmt.Sprintf("%v", this.Key) + `,`,
`Expiry:` + fmt.Sprintf("%v", this.Expiry) + `,`,
`Cardinality:` + fmt.Sprintf("%v", this.Cardinality) + `,`,
`}`,
}, "")
return s
@ -404,7 +460,7 @@ func (m *Entry) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@ -432,7 +488,7 @@ func (m *Entry) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= (int(b) & 0x7F) << shift
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
@ -441,6 +497,9 @@ func (m *Entry) Unmarshal(dAtA []byte) error {
return ErrInvalidLengthCachingIndexClient
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthCachingIndexClient
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
@ -462,7 +521,7 @@ func (m *Entry) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= (int(b) & 0x7F) << shift
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
@ -471,6 +530,9 @@ func (m *Entry) Unmarshal(dAtA []byte) error {
return ErrInvalidLengthCachingIndexClient
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthCachingIndexClient
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
@ -487,6 +549,9 @@ func (m *Entry) Unmarshal(dAtA []byte) error {
if skippy < 0 {
return ErrInvalidLengthCachingIndexClient
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthCachingIndexClient
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
@ -514,7 +579,7 @@ func (m *ReadBatch) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@ -542,7 +607,7 @@ func (m *ReadBatch) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
@ -551,6 +616,9 @@ func (m *ReadBatch) Unmarshal(dAtA []byte) error {
return ErrInvalidLengthCachingIndexClient
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthCachingIndexClient
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
@ -573,7 +641,7 @@ func (m *ReadBatch) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@ -583,6 +651,9 @@ func (m *ReadBatch) Unmarshal(dAtA []byte) error {
return ErrInvalidLengthCachingIndexClient
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthCachingIndexClient
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
@ -602,7 +673,26 @@ func (m *ReadBatch) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
m.Expiry |= (int64(b) & 0x7F) << shift
m.Expiry |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 4:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Cardinality", wireType)
}
m.Cardinality = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowCachingIndexClient
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Cardinality |= int32(b&0x7F) << shift
if b < 0x80 {
break
}
@ -616,6 +706,9 @@ func (m *ReadBatch) Unmarshal(dAtA []byte) error {
if skippy < 0 {
return ErrInvalidLengthCachingIndexClient
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthCachingIndexClient
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
@ -682,10 +775,13 @@ func skipCachingIndexClient(dAtA []byte) (n int, err error) {
break
}
}
iNdEx += length
if length < 0 {
return 0, ErrInvalidLengthCachingIndexClient
}
iNdEx += length
if iNdEx < 0 {
return 0, ErrInvalidLengthCachingIndexClient
}
return iNdEx, nil
case 3:
for {
@ -714,6 +810,9 @@ func skipCachingIndexClient(dAtA []byte) (n int, err error) {
return 0, err
}
iNdEx = start + next
if iNdEx < 0 {
return 0, ErrInvalidLengthCachingIndexClient
}
}
return iNdEx, nil
case 4:
@ -732,32 +831,3 @@ var (
ErrInvalidLengthCachingIndexClient = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowCachingIndexClient = fmt.Errorf("proto: integer overflow")
)
func init() {
proto.RegisterFile("github.com/cortexproject/cortex/pkg/chunk/storage/caching_index_client.proto", fileDescriptor_caching_index_client_2f4bf220288f700f)
}
var fileDescriptor_caching_index_client_2f4bf220288f700f = []byte{
// 331 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x90, 0xb1, 0x4e, 0xeb, 0x30,
0x14, 0x86, 0xe3, 0x9b, 0xdb, 0x54, 0x35, 0x08, 0xa1, 0x0c, 0x28, 0x62, 0x70, 0xab, 0x4e, 0x5d,
0x88, 0x25, 0xca, 0xc6, 0x16, 0xc4, 0xc6, 0x42, 0x90, 0x58, 0xab, 0xd4, 0x3d, 0x24, 0xa6, 0xa9,
0x1d, 0xb9, 0x0e, 0x34, 0x1b, 0x8f, 0xc0, 0x63, 0xb0, 0xf1, 0x1a, 0x1d, 0x3b, 0x56, 0x0c, 0x15,
0x75, 0x17, 0xc6, 0x3e, 0x02, 0xaa, 0x09, 0x12, 0x23, 0x12, 0xdb, 0xf9, 0xe4, 0xe3, 0xcf, 0xbf,
0x7f, 0x7c, 0x95, 0x72, 0x9d, 0x95, 0xc3, 0x90, 0xc9, 0x09, 0x65, 0x52, 0x69, 0x98, 0x15, 0x4a,
0xde, 0x03, 0xd3, 0x35, 0xd1, 0x62, 0x9c, 0x52, 0x96, 0x95, 0x62, 0x4c, 0xa7, 0x5a, 0xaa, 0x24,
0x05, 0xca, 0x12, 0x96, 0x71, 0x91, 0x0e, 0xb8, 0x18, 0xc1, 0x6c, 0xc0, 0x72, 0x0e, 0x42, 0x87,
0x85, 0x92, 0x5a, 0xfa, 0xcd, 0x7a, 0xe7, 0xf8, 0xe4, 0x87, 0x36, 0x95, 0xa9, 0xa4, 0xf6, 0x7c,
0x58, 0xde, 0x59, 0xb2, 0x60, 0xa7, 0xaf, 0x7b, 0xdd, 0x57, 0x84, 0x1b, 0x97, 0x42, 0xab, 0xca,
0xbf, 0xc1, 0xde, 0x85, 0xcc, 0xcb, 0x89, 0x08, 0x50, 0x07, 0xf5, 0xf6, 0xa3, 0xf3, 0xf9, 0xaa,
0xed, 0xbc, 0xad, 0xda, 0xfd, 0xdf, 0xe4, 0x2c, 0x35, 0xcf, 0xe9, 0x23, 0x57, 0x10, 0x46, 0x95,
0x86, 0x69, 0xec, 0x31, 0xab, 0xf2, 0xaf, 0x71, 0xe3, 0x36, 0xc9, 0x4b, 0x08, 0xfe, 0xfd, 0xdd,
0xd9, 0x78, 0xd8, 0x99, 0xba, 0x80, 0x5b, 0x31, 0x24, 0xa3, 0x28, 0xd1, 0x2c, 0xf3, 0x43, 0xdc,
0x04, 0xa1, 0x15, 0x87, 0x69, 0x80, 0x3a, 0x6e, 0x6f, 0xef, 0xf4, 0x20, 0xac, 0x8b, 0x08, 0xed,
0xaf, 0xa2, 0xff, 0xbb, 0x17, 0xe3, 0xef, 0x25, 0xff, 0x10, 0xbb, 0x63, 0xa8, 0x6c, 0x9a, 0x56,
0xbc, 0x1b, 0xfd, 0x23, 0xec, 0xc1, 0xac, 0xe0, 0xaa, 0x0a, 0xdc, 0x0e, 0xea, 0xb9, 0x71, 0x4d,
0xd1, 0xd9, 0x62, 0x4d, 0x9c, 0xe5, 0x9a, 0x38, 0xdb, 0x35, 0x41, 0x4f, 0x86, 0xa0, 0x17, 0x43,
0xd0, 0xdc, 0x10, 0xb4, 0x30, 0x04, 0xbd, 0x1b, 0x82, 0x3e, 0x0c, 0x71, 0xb6, 0x86, 0xa0, 0xe7,
0x0d, 0x71, 0x16, 0x1b, 0xe2, 0x2c, 0x37, 0xc4, 0x19, 0x7a, 0xb6, 0xd5, 0xfe, 0x67, 0x00, 0x00,
0x00, 0xff, 0xff, 0x95, 0x6d, 0x6d, 0xd0, 0xdd, 0x01, 0x00, 0x00,
}

@ -8,8 +8,8 @@ option (gogoproto.marshaler_all) = true;
option (gogoproto.unmarshaler_all) = true;
message Entry {
bytes Column = 1 [(gogoproto.customtype) = "github.com/cortexproject/cortex/pkg/util/wire.Bytes", (gogoproto.nullable) = false];
bytes Value = 2 [(gogoproto.customtype) = "github.com/cortexproject/cortex/pkg/util/wire.Bytes", (gogoproto.nullable) = false];
bytes Column = 1 [(gogoproto.customtype) = "Bytes", (gogoproto.nullable) = false];
bytes Value = 2 [(gogoproto.customtype) = "Bytes", (gogoproto.nullable) = false];
}
message ReadBatch {
@ -18,4 +18,8 @@ message ReadBatch {
// The time at which the key expires.
int64 expiry = 3;
// The number of entries; used for cardinality limiting.
// entries will be empty when this is set.
int32 cardinality = 4;
}

@ -98,7 +98,7 @@ func NewStore(cfg Config, storeCfg chunk.StoreConfig, schemaCfg chunk.SchemaConf
if err != nil {
return nil, errors.Wrap(err, "error creating index client")
}
index = newCachingIndexClient(index, tieredCache, cfg.IndexCacheValidity)
index = newCachingIndexClient(index, tieredCache, cfg.IndexCacheValidity, limits)
objectStoreType := s.ObjectType
if objectStoreType == "" {

@ -1,11 +1,11 @@
package client
import (
"bytes"
stdjson "encoding/json"
"fmt"
"sort"
"strconv"
"strings"
"time"
"unsafe"
@ -16,22 +16,6 @@ import (
var json = jsoniter.ConfigCompatibleWithStandardLibrary
// FromWriteRequest converts a WriteRequest proto into an array of samples.
func FromWriteRequest(req *WriteRequest) []model.Sample {
// Just guess that there is one sample per timeseries
samples := make([]model.Sample, 0, len(req.Timeseries))
for _, ts := range req.Timeseries {
for _, s := range ts.Samples {
samples = append(samples, model.Sample{
Metric: FromLabelPairs(ts.Labels),
Value: model.SampleValue(s.Value),
Timestamp: model.Time(s.TimestampMs),
})
}
}
return samples
}
// ToWriteRequest converts an array of samples into a WriteRequest proto.
func ToWriteRequest(samples []model.Sample, source WriteRequest_SourceEnum) *WriteRequest {
req := &WriteRequest{
@ -42,7 +26,7 @@ func ToWriteRequest(samples []model.Sample, source WriteRequest_SourceEnum) *Wri
for _, s := range samples {
ts := PreallocTimeseries{
TimeSeries: TimeSeries{
Labels: ToLabelPairs(s.Metric),
Labels: FromMetricsToLabelAdapters(s.Metric),
Samples: []Sample{
{
Value: float64(s.Value),
@ -87,7 +71,7 @@ func ToQueryResponse(matrix model.Matrix) *QueryResponse {
resp := &QueryResponse{}
for _, ss := range matrix {
ts := TimeSeries{
Labels: ToLabelPairs(ss.Metric),
Labels: FromMetricsToLabelAdapters(ss.Metric),
Samples: make([]Sample, 0, len(ss.Values)),
}
for _, s := range ss.Values {
@ -106,7 +90,7 @@ func FromQueryResponse(resp *QueryResponse) model.Matrix {
m := make(model.Matrix, 0, len(resp.Timeseries))
for _, ts := range resp.Timeseries {
var ss model.SampleStream
ss.Metric = FromLabelPairs(ts.Labels)
ss.Metric = FromLabelAdaptersToMetric(ts.Labels)
ss.Values = make([]model.SamplePair, 0, len(ts.Samples))
for _, s := range ts.Samples {
ss.Values = append(ss.Values, model.SamplePair{
@ -153,7 +137,7 @@ func FromMetricsForLabelMatchersRequest(req *MetricsForLabelMatchersRequest) (mo
func FromMetricsForLabelMatchersResponse(resp *MetricsForLabelMatchersResponse) []model.Metric {
metrics := []model.Metric{}
for _, m := range resp.Metric {
metrics = append(metrics, FromLabelPairs(m.Labels))
metrics = append(metrics, FromLabelAdaptersToMetric(m.Labels))
}
return metrics
}
@ -208,70 +192,63 @@ func fromLabelMatchers(matchers []*LabelMatcher) ([]*labels.Matcher, error) {
return result, nil
}
// ToLabelPairs builds a []LabelPair from a model.Metric
func ToLabelPairs(metric model.Metric) []LabelPair {
labelPairs := make([]LabelPair, 0, len(metric))
for k, v := range metric {
labelPairs = append(labelPairs, LabelPair{
Name: []byte(k),
Value: []byte(v),
})
}
sort.Sort(byLabel(labelPairs)) // The labels should be sorted upon initialisation.
return labelPairs
// FromLabelAdaptersToLabels casts []LabelAdapter to labels.Labels.
// It uses unsafe, but as LabelAdapter == labels.Label this should be safe.
// This allows us to use labels.Labels directly in protos.
func FromLabelAdaptersToLabels(ls []LabelAdapter) labels.Labels {
return *(*labels.Labels)(unsafe.Pointer(&ls))
}
type byLabel []LabelPair
func (s byLabel) Len() int { return len(s) }
func (s byLabel) Less(i, j int) bool { return bytes.Compare(s[i].Name, s[j].Name) < 0 }
func (s byLabel) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// FromLabelPairs unpack a []LabelPair to a model.Metric
func FromLabelPairs(labelPairs []LabelPair) model.Metric {
metric := make(model.Metric, len(labelPairs))
for _, l := range labelPairs {
metric[model.LabelName(l.Name)] = model.LabelValue(l.Value)
}
return metric
// FromLabelsToLabelAdapaters casts labels.Labels to []LabelAdapter.
// It uses unsafe, but as LabelAdapter == labels.Label this should be safe.
// This allows us to use labels.Labels directly in protos.
func FromLabelsToLabelAdapaters(ls labels.Labels) []LabelAdapter {
return *(*[]LabelAdapter)(unsafe.Pointer(&ls))
}
// FromLabelPairsToLabels unpack a []LabelPair to a labels.Labels
func FromLabelPairsToLabels(labelPairs []LabelPair) labels.Labels {
ls := make(labels.Labels, 0, len(labelPairs))
for _, l := range labelPairs {
ls = append(ls, labels.Label{
Name: string(l.Name),
Value: string(l.Value),
})
// FromLabelAdaptersToMetric converts []LabelAdapter to a model.Metric.
// Don't do this on any performance sensitive paths.
func FromLabelAdaptersToMetric(ls []LabelAdapter) model.Metric {
result := make(model.Metric, len(ls))
for _, l := range ls {
result[model.LabelName(l.Name)] = model.LabelValue(l.Value)
}
return ls
return result
}
// FromLabelsToLabelPairs converts labels.Labels to []LabelPair
func FromLabelsToLabelPairs(s labels.Labels) []LabelPair {
labelPairs := make([]LabelPair, 0, len(s))
for _, v := range s {
labelPairs = append(labelPairs, LabelPair{
Name: []byte(v.Name),
Value: []byte(v.Value),
// FromMetricsToLabelAdapters converts model.Metric to []LabelAdapter.
// Don't do this on any performance sensitive paths.
// The result is sorted.
func FromMetricsToLabelAdapters(metric model.Metric) []LabelAdapter {
result := make([]LabelAdapter, 0, len(metric))
for k, v := range metric {
result = append(result, LabelAdapter{
Name: string(k),
Value: string(v),
})
}
return labelPairs // note already sorted
sort.Sort(byLabel(result)) // The labels should be sorted upon initialisation.
return result
}
type byLabel []LabelAdapter
func (s byLabel) Len() int { return len(s) }
func (s byLabel) Less(i, j int) bool { return strings.Compare(s[i].Name, s[j].Name) < 0 }
func (s byLabel) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// FastFingerprint runs the same algorithm as Prometheus labelSetToFastFingerprint()
func FastFingerprint(labelPairs []LabelPair) model.Fingerprint {
if len(labelPairs) == 0 {
func FastFingerprint(ls []LabelAdapter) model.Fingerprint {
if len(ls) == 0 {
return model.Metric(nil).FastFingerprint()
}
var result uint64
for _, pair := range labelPairs {
for _, l := range ls {
sum := hashNew()
sum = hashAdd(sum, pair.Name)
sum = hashAdd(sum, l.Name)
sum = hashAddByte(sum, model.SeparatorByte)
sum = hashAdd(sum, pair.Value)
sum = hashAdd(sum, l.Value)
result ^= sum
}
return model.Fingerprint(result)

File diff suppressed because it is too large Load Diff

@ -104,7 +104,7 @@ message MetricsForLabelMatchersResponse {
message TimeSeriesChunk {
string from_ingester_id = 1;
string user_id = 2;
repeated LabelPair labels = 3 [(gogoproto.nullable) = false];
repeated LabelPair labels = 3 [(gogoproto.nullable) = false, (gogoproto.customtype) = "LabelAdapter"];
repeated Chunk chunks = 4 [(gogoproto.nullable) = false];
}
@ -119,14 +119,14 @@ message TransferChunksResponse {
}
message TimeSeries {
repeated LabelPair labels = 1 [(gogoproto.nullable) = false];
repeated LabelPair labels = 1 [(gogoproto.nullable) = false, (gogoproto.customtype) = "LabelAdapter"];
// Sorted by time, oldest sample first.
repeated Sample samples = 2 [(gogoproto.nullable) = false];
}
message LabelPair {
bytes name = 1 [(gogoproto.customtype) = "github.com/cortexproject/cortex/pkg/util/wire.Bytes", (gogoproto.nullable) = false];
bytes value = 2 [(gogoproto.customtype) = "github.com/cortexproject/cortex/pkg/util/wire.Bytes", (gogoproto.nullable) = false];
bytes name = 1;
bytes value = 2;
}
message Sample {
@ -139,7 +139,7 @@ message LabelMatchers {
}
message Metric {
repeated LabelPair labels = 1 [(gogoproto.nullable) = false];
repeated LabelPair labels = 1 [(gogoproto.nullable) = false, (gogoproto.customtype) = "LabelAdapter"];
}
enum MatchType {

@ -19,6 +19,8 @@ package client
const (
offset64 = 14695981039346656037
prime64 = 1099511628211
offset32 = 2166136261
prime32 = 16777619
)
// hashNew initializies a new fnv64a hash value.
@ -27,7 +29,8 @@ func hashNew() uint64 {
}
// hashAdd adds a string to a fnv64a hash value, returning the updated hash.
func hashAdd(h uint64, s []byte) uint64 {
// Note this is the same algorithm as Go stdlib `sum64a.Write()`
func hashAdd(h uint64, s string) uint64 {
for i := 0; i < len(s); i++ {
h ^= uint64(s[i])
h *= prime64
@ -41,3 +44,18 @@ func hashAddByte(h uint64, b byte) uint64 {
h *= prime64
return h
}
// HashNew32 initializies a new fnv32 hash value.
func HashNew32() uint32 {
return offset32
}
// HashAdd32 adds a string to a fnv32 hash value, returning the updated hash.
// Note this is the same algorithm as Go stdlib `sum32.Write()`
func HashAdd32(h uint32, s string) uint32 {
for i := 0; i < len(s); i++ {
h *= prime32
h ^= uint32(s[i])
}
return h
}

@ -1,6 +1,14 @@
package client
import "flag"
import (
"flag"
"fmt"
"io"
"strings"
"unsafe"
"github.com/prometheus/prometheus/pkg/labels"
)
var (
expectedTimeseries = 100
@ -37,7 +45,182 @@ type PreallocTimeseries struct {
// Unmarshal implements proto.Message.
func (p *PreallocTimeseries) Unmarshal(dAtA []byte) error {
p.Labels = make([]LabelPair, 0, expectedLabels)
p.Labels = make([]LabelAdapter, 0, expectedLabels)
p.Samples = make([]Sample, 0, expectedSamplesPerSeries)
return p.TimeSeries.Unmarshal(dAtA)
}
// LabelAdapter is a labels.Label that can be marshalled to/from protos.
type LabelAdapter labels.Label
// Marshal implements proto.Marshaller.
func (bs *LabelAdapter) Marshal() ([]byte, error) {
buf := make([]byte, bs.Size())
_, err := bs.MarshalTo(buf)
return buf, err
}
// MarshalTo implements proto.Marshaller.
func (bs *LabelAdapter) MarshalTo(buf []byte) (n int, err error) {
var i int
ls := (*labels.Label)(bs)
buf[i] = 0xa
i++
i = encodeVarintCortex(buf, i, uint64(len(ls.Name)))
i += copy(buf[i:], ls.Name)
buf[i] = 0x12
i++
i = encodeVarintCortex(buf, i, uint64(len(ls.Value)))
i += copy(buf[i:], ls.Value)
return i, nil
}
// Unmarshal a LabelAdapater, implements proto.Unmarshaller.
// NB this is a copy of the autogenerated code to unmarshal a LabelPair,
// with the byte copying replaced with a yoloString.
func (bs *LabelAdapter) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowCortex
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: LabelPair: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: LabelPair: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowCortex
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthCortex
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthCortex
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
bs.Name = yoloString(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowCortex
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthCortex
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthCortex
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
bs.Value = yoloString(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipCortex(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthCortex
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthCortex
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func yoloString(buf []byte) string {
return *((*string)(unsafe.Pointer(&buf)))
}
// Size implements proto.Sizer.
func (bs *LabelAdapter) Size() int {
ls := (*labels.Label)(bs)
var n int
l := len(ls.Name)
n += 1 + l + sovCortex(uint64(l))
l = len(ls.Value)
n += 1 + l + sovCortex(uint64(l))
return n
}
// Equal implements proto.Equaler.
func (bs *LabelAdapter) Equal(other LabelAdapter) bool {
return bs.Name == other.Name && bs.Value == other.Value
}
// Compare implements proto.Comparer.
func (bs *LabelAdapter) Compare(other LabelAdapter) int {
if c := strings.Compare(bs.Name, other.Name); c != 0 {
return c
}
return strings.Compare(bs.Value, other.Value)
}

@ -32,7 +32,7 @@ func New() *InvertedIndex {
}
// Add a fingerprint under the specified labels.
func (ii *InvertedIndex) Add(labels []client.LabelPair, fp model.Fingerprint) labels.Labels {
func (ii *InvertedIndex) Add(labels []client.LabelAdapter, fp model.Fingerprint) labels.Labels {
shard := &ii.shards[util.HashFP(fp)%indexShards]
return shard.add(labels, fp)
}
@ -49,7 +49,6 @@ func (ii *InvertedIndex) Lookup(matchers []*labels.Matcher) []model.Fingerprint
result = append(result, fps...)
}
sort.Sort(fingerprints(result))
return result
}
@ -105,25 +104,31 @@ type indexShard struct {
pad [cacheLineSize - unsafe.Sizeof(sync.Mutex{}) - unsafe.Sizeof(unlockIndex{})]byte
}
func copyString(s string) string {
return string([]byte(s))
}
// add metric to the index; return all the name/value pairs as strings from the index, sorted
func (shard *indexShard) add(metric []client.LabelPair, fp model.Fingerprint) labels.Labels {
func (shard *indexShard) add(metric []client.LabelAdapter, fp model.Fingerprint) labels.Labels {
shard.mtx.Lock()
defer shard.mtx.Unlock()
internedLabels := make(labels.Labels, len(metric))
for i, pair := range metric {
values, ok := shard.idx[string(pair.Name)]
values, ok := shard.idx[pair.Name]
if !ok {
values = indexEntry{
name: string(pair.Name),
name: copyString(pair.Name),
fps: map[string]indexValueEntry{},
}
shard.idx[values.name] = values
}
fingerprints, ok := values.fps[string(pair.Value)]
fingerprints, ok := values.fps[pair.Value]
if !ok {
fingerprints = indexValueEntry{value: string(pair.Value)}
fingerprints = indexValueEntry{
value: copyString(pair.Value),
}
}
// Insert into the right position to keep fingerprints sorted
j := sort.Search(len(fingerprints.fps), func(i int) bool {
@ -133,7 +138,7 @@ func (shard *indexShard) add(metric []client.LabelPair, fp model.Fingerprint) la
copy(fingerprints.fps[j+1:], fingerprints.fps[j:])
fingerprints.fps[j] = fp
values.fps[fingerprints.value] = fingerprints
internedLabels[i] = labels.Label{Name: string(values.name), Value: string(fingerprints.value)}
internedLabels[i] = labels.Label{Name: values.name, Value: fingerprints.value}
}
sort.Sort(internedLabels)
return internedLabels
@ -162,7 +167,7 @@ func (shard *indexShard) lookup(matchers []*labels.Matcher) []model.Fingerprint
// accumulate the matching fingerprints (which are all distinct)
// then sort to maintain the invariant
for value, fps := range values.fps {
if matcher.Matches(string(value)) {
if matcher.Matches(value) {
toIntersect = append(toIntersect, fps.fps...)
}
}
@ -213,7 +218,7 @@ func (shard *indexShard) delete(labels labels.Labels, fp model.Fingerprint) {
defer shard.mtx.Unlock()
for _, pair := range labels {
name, value := string(pair.Name), string(pair.Value)
name, value := pair.Name, pair.Value
values, ok := shard.idx[name]
if !ok {
continue

@ -3,18 +3,17 @@
package ring
import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
import _ "github.com/gogo/protobuf/gogoproto"
import strconv "strconv"
import strings "strings"
import reflect "reflect"
import github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys"
import io "io"
import (
fmt "fmt"
_ "github.com/gogo/protobuf/gogoproto"
proto "github.com/gogo/protobuf/proto"
github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys"
io "io"
math "math"
reflect "reflect"
strconv "strconv"
strings "strings"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
@ -42,6 +41,7 @@ var IngesterState_name = map[int32]string{
2: "PENDING",
3: "JOINING",
}
var IngesterState_value = map[string]int32{
"ACTIVE": 0,
"LEAVING": 1,
@ -50,18 +50,18 @@ var IngesterState_value = map[string]int32{
}
func (IngesterState) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_ring_35bba6cb303d16e3, []int{0}
return fileDescriptor_7ebe6ffe1686e76b, []int{0}
}
type Desc struct {
Ingesters map[string]IngesterDesc `protobuf:"bytes,1,rep,name=ingesters" json:"ingesters" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value"`
Tokens []TokenDesc `protobuf:"bytes,2,rep,name=tokens" json:"tokens"`
Ingesters map[string]IngesterDesc `protobuf:"bytes,1,rep,name=ingesters,proto3" json:"ingesters" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Tokens []TokenDesc `protobuf:"bytes,2,rep,name=tokens,proto3" json:"tokens"`
}
func (m *Desc) Reset() { *m = Desc{} }
func (*Desc) ProtoMessage() {}
func (*Desc) Descriptor() ([]byte, []int) {
return fileDescriptor_ring_35bba6cb303d16e3, []int{0}
return fileDescriptor_7ebe6ffe1686e76b, []int{0}
}
func (m *Desc) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -78,8 +78,8 @@ func (m *Desc) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return b[:n], nil
}
}
func (dst *Desc) XXX_Merge(src proto.Message) {
xxx_messageInfo_Desc.Merge(dst, src)
func (m *Desc) XXX_Merge(src proto.Message) {
xxx_messageInfo_Desc.Merge(m, src)
}
func (m *Desc) XXX_Size() int {
return m.Size()
@ -108,13 +108,13 @@ type IngesterDesc struct {
Addr string `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"`
Timestamp int64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
State IngesterState `protobuf:"varint,3,opt,name=state,proto3,enum=ring.IngesterState" json:"state,omitempty"`
Tokens []uint32 `protobuf:"varint,6,rep,packed,name=tokens" json:"tokens,omitempty"`
Tokens []uint32 `protobuf:"varint,6,rep,packed,name=tokens,proto3" json:"tokens,omitempty"`
}
func (m *IngesterDesc) Reset() { *m = IngesterDesc{} }
func (*IngesterDesc) ProtoMessage() {}
func (*IngesterDesc) Descriptor() ([]byte, []int) {
return fileDescriptor_ring_35bba6cb303d16e3, []int{1}
return fileDescriptor_7ebe6ffe1686e76b, []int{1}
}
func (m *IngesterDesc) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -131,8 +131,8 @@ func (m *IngesterDesc) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)
return b[:n], nil
}
}
func (dst *IngesterDesc) XXX_Merge(src proto.Message) {
xxx_messageInfo_IngesterDesc.Merge(dst, src)
func (m *IngesterDesc) XXX_Merge(src proto.Message) {
xxx_messageInfo_IngesterDesc.Merge(m, src)
}
func (m *IngesterDesc) XXX_Size() int {
return m.Size()
@ -179,7 +179,7 @@ type TokenDesc struct {
func (m *TokenDesc) Reset() { *m = TokenDesc{} }
func (*TokenDesc) ProtoMessage() {}
func (*TokenDesc) Descriptor() ([]byte, []int) {
return fileDescriptor_ring_35bba6cb303d16e3, []int{2}
return fileDescriptor_7ebe6ffe1686e76b, []int{2}
}
func (m *TokenDesc) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -196,8 +196,8 @@ func (m *TokenDesc) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return b[:n], nil
}
}
func (dst *TokenDesc) XXX_Merge(src proto.Message) {
xxx_messageInfo_TokenDesc.Merge(dst, src)
func (m *TokenDesc) XXX_Merge(src proto.Message) {
xxx_messageInfo_TokenDesc.Merge(m, src)
}
func (m *TokenDesc) XXX_Size() int {
return m.Size()
@ -223,12 +223,49 @@ func (m *TokenDesc) GetIngester() string {
}
func init() {
proto.RegisterEnum("ring.IngesterState", IngesterState_name, IngesterState_value)
proto.RegisterType((*Desc)(nil), "ring.Desc")
proto.RegisterMapType((map[string]IngesterDesc)(nil), "ring.Desc.IngestersEntry")
proto.RegisterType((*IngesterDesc)(nil), "ring.IngesterDesc")
proto.RegisterType((*TokenDesc)(nil), "ring.TokenDesc")
proto.RegisterEnum("ring.IngesterState", IngesterState_name, IngesterState_value)
}
func init() {
proto.RegisterFile("github.com/cortexproject/cortex/pkg/ring/ring.proto", fileDescriptor_7ebe6ffe1686e76b)
}
var fileDescriptor_7ebe6ffe1686e76b = []byte{
// 440 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x92, 0xcf, 0x6e, 0xd3, 0x40,
0x10, 0xc6, 0x77, 0xe2, 0x3f, 0xc4, 0x13, 0x52, 0xac, 0x05, 0x21, 0x13, 0xa1, 0xc5, 0xca, 0xc9,
0x20, 0x35, 0x91, 0x52, 0x0e, 0x08, 0xa9, 0x87, 0x86, 0x46, 0x28, 0x11, 0x0a, 0x95, 0xa9, 0x7a,
0x4f, 0xd2, 0xc5, 0x84, 0x90, 0xac, 0x65, 0x6f, 0x10, 0xbd, 0xf1, 0x06, 0xf0, 0x18, 0x3c, 0x09,
0xea, 0x31, 0xc7, 0x9e, 0x10, 0x71, 0x2e, 0x1c, 0xfb, 0x08, 0x68, 0xd7, 0x76, 0x9a, 0x5c, 0xac,
0xf9, 0xed, 0x37, 0xdf, 0xb7, 0x33, 0xd6, 0xe2, 0x51, 0x34, 0x95, 0x9f, 0x96, 0xe3, 0xd6, 0x44,
0xcc, 0xdb, 0x13, 0x91, 0x48, 0xfe, 0x2d, 0x4e, 0xc4, 0x67, 0x3e, 0x91, 0x05, 0xb5, 0xe3, 0x59,
0xd4, 0x4e, 0xa6, 0x8b, 0xfc, 0xd3, 0x8a, 0x13, 0x21, 0x05, 0x35, 0x55, 0xdd, 0x38, 0xdc, 0xb1,
0x46, 0x22, 0x12, 0x6d, 0x2d, 0x8e, 0x97, 0x1f, 0x35, 0x69, 0xd0, 0x55, 0x6e, 0x6a, 0xfe, 0x06,
0x34, 0x4f, 0x79, 0x3a, 0xa1, 0xc7, 0xe8, 0x4c, 0x17, 0x11, 0x4f, 0x25, 0x4f, 0x52, 0x0f, 0x7c,
0x23, 0xa8, 0x75, 0x9e, 0xb4, 0x74, 0xba, 0x92, 0x5b, 0xfd, 0x52, 0xeb, 0x2d, 0x64, 0x72, 0xd5,
0x35, 0xaf, 0xff, 0x3c, 0x23, 0xe1, 0x9d, 0x83, 0x1e, 0xa2, 0x2d, 0xc5, 0x8c, 0x2f, 0x52, 0xaf,
0xa2, 0xbd, 0x0f, 0x72, 0xef, 0xb9, 0x3a, 0x53, 0x01, 0x85, 0xa3, 0x68, 0x6a, 0x9c, 0xe1, 0xc1,
0x7e, 0x22, 0x75, 0xd1, 0x98, 0xf1, 0x2b, 0x0f, 0x7c, 0x08, 0x9c, 0x50, 0x95, 0x34, 0x40, 0xeb,
0xeb, 0xe8, 0xcb, 0x92, 0x7b, 0x15, 0x1f, 0x82, 0x5a, 0x87, 0xe6, 0x89, 0xa5, 0x4d, 0x85, 0x86,
0x79, 0xc3, 0xeb, 0xca, 0x2b, 0x68, 0xfe, 0x00, 0xbc, 0xbf, 0xab, 0x51, 0x8a, 0xe6, 0xe8, 0xf2,
0x32, 0x29, 0x12, 0x75, 0x4d, 0x9f, 0xa2, 0x23, 0xa7, 0x73, 0x9e, 0xca, 0xd1, 0x3c, 0xd6, 0xb1,
0x46, 0x78, 0x77, 0x40, 0x9f, 0xa3, 0x95, 0xca, 0x91, 0xe4, 0x9e, 0xe1, 0x43, 0x70, 0xd0, 0x79,
0xb8, 0x7f, 0xe1, 0x07, 0x25, 0x85, 0x79, 0x07, 0x7d, 0xbc, 0x5d, 0xd7, 0xf6, 0x8d, 0xa0, 0x5e,
0xee, 0x35, 0x30, 0xab, 0xa6, 0x6b, 0x0d, 0xcc, 0xaa, 0xe5, 0xda, 0xcd, 0x63, 0x74, 0xb6, 0xeb,
0xd3, 0x47, 0x68, 0xe9, 0x16, 0x3d, 0x4e, 0x3d, 0xcc, 0x81, 0x36, 0xb0, 0x5a, 0xfe, 0x42, 0x3d,
0x8e, 0x13, 0x6e, 0xf9, 0x45, 0x17, 0xeb, 0x7b, 0x57, 0x53, 0x44, 0xfb, 0xe4, 0xcd, 0x79, 0xff,
0xa2, 0xe7, 0x12, 0x5a, 0xc3, 0x7b, 0xef, 0x7a, 0x27, 0x17, 0xfd, 0xe1, 0x5b, 0x17, 0x14, 0x9c,
0xf5, 0x86, 0xa7, 0x0a, 0x2a, 0x0a, 0x06, 0xef, 0xfb, 0x43, 0x05, 0x46, 0xf7, 0xe5, 0x6a, 0xcd,
0xc8, 0xcd, 0x9a, 0x91, 0xdb, 0x35, 0x83, 0xef, 0x19, 0x83, 0x5f, 0x19, 0x83, 0xeb, 0x8c, 0xc1,
0x2a, 0x63, 0xf0, 0x37, 0x63, 0xf0, 0x2f, 0x63, 0xe4, 0x36, 0x63, 0xf0, 0x73, 0xc3, 0xc8, 0x6a,
0xc3, 0xc8, 0xcd, 0x86, 0x91, 0xb1, 0xad, 0x9f, 0xc6, 0xd1, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
0xab, 0x96, 0x85, 0x85, 0x86, 0x02, 0x00, 0x00,
}
func (x IngesterState) String() string {
s, ok := IngesterState_name[int32(x)]
if ok {
@ -435,9 +472,9 @@ func (m *Desc) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x12
i++
i = encodeVarintRing(dAtA, i, uint64((&v).Size()))
n1, err := (&v).MarshalTo(dAtA[i:])
if err != nil {
return 0, err
n1, err1 := (&v).MarshalTo(dAtA[i:])
if err1 != nil {
return 0, err1
}
i += n1
}
@ -629,6 +666,11 @@ func (this *Desc) String() string {
if this == nil {
return "nil"
}
repeatedStringForTokens := "[]TokenDesc{"
for _, f := range this.Tokens {
repeatedStringForTokens += strings.Replace(strings.Replace(f.String(), "TokenDesc", "TokenDesc", 1), `&`, ``, 1) + ","
}
repeatedStringForTokens += "}"
keysForIngesters := make([]string, 0, len(this.Ingesters))
for k, _ := range this.Ingesters {
keysForIngesters = append(keysForIngesters, k)
@ -641,7 +683,7 @@ func (this *Desc) String() string {
mapStringForIngesters += "}"
s := strings.Join([]string{`&Desc{`,
`Ingesters:` + mapStringForIngesters + `,`,
`Tokens:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Tokens), "TokenDesc", "TokenDesc", 1), `&`, ``, 1) + `,`,
`Tokens:` + repeatedStringForTokens + `,`,
`}`,
}, "")
return s
@ -693,7 +735,7 @@ func (m *Desc) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@ -721,7 +763,7 @@ func (m *Desc) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
@ -730,6 +772,9 @@ func (m *Desc) Unmarshal(dAtA []byte) error {
return ErrInvalidLengthRing
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthRing
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
@ -750,7 +795,7 @@ func (m *Desc) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@ -767,7 +812,7 @@ func (m *Desc) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapkey |= (uint64(b) & 0x7F) << shift
stringLenmapkey |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@ -777,6 +822,9 @@ func (m *Desc) Unmarshal(dAtA []byte) error {
return ErrInvalidLengthRing
}
postStringIndexmapkey := iNdEx + intStringLenmapkey
if postStringIndexmapkey < 0 {
return ErrInvalidLengthRing
}
if postStringIndexmapkey > l {
return io.ErrUnexpectedEOF
}
@ -793,7 +841,7 @@ func (m *Desc) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
mapmsglen |= (int(b) & 0x7F) << shift
mapmsglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
@ -802,7 +850,7 @@ func (m *Desc) Unmarshal(dAtA []byte) error {
return ErrInvalidLengthRing
}
postmsgIndex := iNdEx + mapmsglen
if mapmsglen < 0 {
if postmsgIndex < 0 {
return ErrInvalidLengthRing
}
if postmsgIndex > l {
@ -844,7 +892,7 @@ func (m *Desc) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
@ -853,6 +901,9 @@ func (m *Desc) Unmarshal(dAtA []byte) error {
return ErrInvalidLengthRing
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthRing
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
@ -870,6 +921,9 @@ func (m *Desc) Unmarshal(dAtA []byte) error {
if skippy < 0 {
return ErrInvalidLengthRing
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthRing
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
@ -897,7 +951,7 @@ func (m *IngesterDesc) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@ -925,7 +979,7 @@ func (m *IngesterDesc) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@ -935,6 +989,9 @@ func (m *IngesterDesc) Unmarshal(dAtA []byte) error {
return ErrInvalidLengthRing
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthRing
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
@ -954,7 +1011,7 @@ func (m *IngesterDesc) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
m.Timestamp |= (int64(b) & 0x7F) << shift
m.Timestamp |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
@ -973,7 +1030,7 @@ func (m *IngesterDesc) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
m.State |= (IngesterState(b) & 0x7F) << shift
m.State |= IngesterState(b&0x7F) << shift
if b < 0x80 {
break
}
@ -990,7 +1047,7 @@ func (m *IngesterDesc) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
v |= (uint32(b) & 0x7F) << shift
v |= uint32(b&0x7F) << shift
if b < 0x80 {
break
}
@ -1007,7 +1064,7 @@ func (m *IngesterDesc) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
packedLen |= (int(b) & 0x7F) << shift
packedLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
@ -1016,12 +1073,15 @@ func (m *IngesterDesc) Unmarshal(dAtA []byte) error {
return ErrInvalidLengthRing
}
postIndex := iNdEx + packedLen
if postIndex < 0 {
return ErrInvalidLengthRing
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
var elementCount int
var count int
for _, integer := range dAtA {
for _, integer := range dAtA[iNdEx:postIndex] {
if integer < 128 {
count++
}
@ -1041,7 +1101,7 @@ func (m *IngesterDesc) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
v |= (uint32(b) & 0x7F) << shift
v |= uint32(b&0x7F) << shift
if b < 0x80 {
break
}
@ -1060,6 +1120,9 @@ func (m *IngesterDesc) Unmarshal(dAtA []byte) error {
if skippy < 0 {
return ErrInvalidLengthRing
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthRing
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
@ -1087,7 +1150,7 @@ func (m *TokenDesc) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@ -1115,7 +1178,7 @@ func (m *TokenDesc) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
m.Token |= (uint32(b) & 0x7F) << shift
m.Token |= uint32(b&0x7F) << shift
if b < 0x80 {
break
}
@ -1134,7 +1197,7 @@ func (m *TokenDesc) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@ -1144,6 +1207,9 @@ func (m *TokenDesc) Unmarshal(dAtA []byte) error {
return ErrInvalidLengthRing
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthRing
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
@ -1158,6 +1224,9 @@ func (m *TokenDesc) Unmarshal(dAtA []byte) error {
if skippy < 0 {
return ErrInvalidLengthRing
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthRing
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
@ -1224,10 +1293,13 @@ func skipRing(dAtA []byte) (n int, err error) {
break
}
}
iNdEx += length
if length < 0 {
return 0, ErrInvalidLengthRing
}
iNdEx += length
if iNdEx < 0 {
return 0, ErrInvalidLengthRing
}
return iNdEx, nil
case 3:
for {
@ -1256,6 +1328,9 @@ func skipRing(dAtA []byte) (n int, err error) {
return 0, err
}
iNdEx = start + next
if iNdEx < 0 {
return 0, ErrInvalidLengthRing
}
}
return iNdEx, nil
case 4:
@ -1274,39 +1349,3 @@ var (
ErrInvalidLengthRing = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowRing = fmt.Errorf("proto: integer overflow")
)
func init() {
proto.RegisterFile("github.com/cortexproject/cortex/pkg/ring/ring.proto", fileDescriptor_ring_35bba6cb303d16e3)
}
var fileDescriptor_ring_35bba6cb303d16e3 = []byte{
// 440 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x92, 0xcf, 0x6e, 0xd3, 0x40,
0x10, 0xc6, 0x77, 0xe2, 0x3f, 0xc4, 0x13, 0x52, 0xac, 0x05, 0x21, 0x13, 0xa1, 0xc5, 0xca, 0xc9,
0x20, 0x35, 0x91, 0x52, 0x0e, 0x08, 0xa9, 0x87, 0x86, 0x46, 0x28, 0x11, 0x0a, 0x95, 0xa9, 0x7a,
0x4f, 0xd2, 0xc5, 0x84, 0x90, 0xac, 0x65, 0x6f, 0x10, 0xbd, 0xf1, 0x06, 0xf0, 0x18, 0x3c, 0x09,
0xea, 0x31, 0xc7, 0x9e, 0x10, 0x71, 0x2e, 0x1c, 0xfb, 0x08, 0x68, 0xd7, 0x76, 0x9a, 0x5c, 0xac,
0xf9, 0xed, 0x37, 0xdf, 0xb7, 0x33, 0xd6, 0xe2, 0x51, 0x34, 0x95, 0x9f, 0x96, 0xe3, 0xd6, 0x44,
0xcc, 0xdb, 0x13, 0x91, 0x48, 0xfe, 0x2d, 0x4e, 0xc4, 0x67, 0x3e, 0x91, 0x05, 0xb5, 0xe3, 0x59,
0xd4, 0x4e, 0xa6, 0x8b, 0xfc, 0xd3, 0x8a, 0x13, 0x21, 0x05, 0x35, 0x55, 0xdd, 0x38, 0xdc, 0xb1,
0x46, 0x22, 0x12, 0x6d, 0x2d, 0x8e, 0x97, 0x1f, 0x35, 0x69, 0xd0, 0x55, 0x6e, 0x6a, 0xfe, 0x06,
0x34, 0x4f, 0x79, 0x3a, 0xa1, 0xc7, 0xe8, 0x4c, 0x17, 0x11, 0x4f, 0x25, 0x4f, 0x52, 0x0f, 0x7c,
0x23, 0xa8, 0x75, 0x9e, 0xb4, 0x74, 0xba, 0x92, 0x5b, 0xfd, 0x52, 0xeb, 0x2d, 0x64, 0x72, 0xd5,
0x35, 0xaf, 0xff, 0x3c, 0x23, 0xe1, 0x9d, 0x83, 0x1e, 0xa2, 0x2d, 0xc5, 0x8c, 0x2f, 0x52, 0xaf,
0xa2, 0xbd, 0x0f, 0x72, 0xef, 0xb9, 0x3a, 0x53, 0x01, 0x85, 0xa3, 0x68, 0x6a, 0x9c, 0xe1, 0xc1,
0x7e, 0x22, 0x75, 0xd1, 0x98, 0xf1, 0x2b, 0x0f, 0x7c, 0x08, 0x9c, 0x50, 0x95, 0x34, 0x40, 0xeb,
0xeb, 0xe8, 0xcb, 0x92, 0x7b, 0x15, 0x1f, 0x82, 0x5a, 0x87, 0xe6, 0x89, 0xa5, 0x4d, 0x85, 0x86,
0x79, 0xc3, 0xeb, 0xca, 0x2b, 0x68, 0xfe, 0x00, 0xbc, 0xbf, 0xab, 0x51, 0x8a, 0xe6, 0xe8, 0xf2,
0x32, 0x29, 0x12, 0x75, 0x4d, 0x9f, 0xa2, 0x23, 0xa7, 0x73, 0x9e, 0xca, 0xd1, 0x3c, 0xd6, 0xb1,
0x46, 0x78, 0x77, 0x40, 0x9f, 0xa3, 0x95, 0xca, 0x91, 0xe4, 0x9e, 0xe1, 0x43, 0x70, 0xd0, 0x79,
0xb8, 0x7f, 0xe1, 0x07, 0x25, 0x85, 0x79, 0x07, 0x7d, 0xbc, 0x5d, 0xd7, 0xf6, 0x8d, 0xa0, 0x5e,
0xee, 0x35, 0x30, 0xab, 0xa6, 0x6b, 0x0d, 0xcc, 0xaa, 0xe5, 0xda, 0xcd, 0x63, 0x74, 0xb6, 0xeb,
0xd3, 0x47, 0x68, 0xe9, 0x16, 0x3d, 0x4e, 0x3d, 0xcc, 0x81, 0x36, 0xb0, 0x5a, 0xfe, 0x42, 0x3d,
0x8e, 0x13, 0x6e, 0xf9, 0x45, 0x17, 0xeb, 0x7b, 0x57, 0x53, 0x44, 0xfb, 0xe4, 0xcd, 0x79, 0xff,
0xa2, 0xe7, 0x12, 0x5a, 0xc3, 0x7b, 0xef, 0x7a, 0x27, 0x17, 0xfd, 0xe1, 0x5b, 0x17, 0x14, 0x9c,
0xf5, 0x86, 0xa7, 0x0a, 0x2a, 0x0a, 0x06, 0xef, 0xfb, 0x43, 0x05, 0x46, 0xf7, 0xe5, 0x6a, 0xcd,
0xc8, 0xcd, 0x9a, 0x91, 0xdb, 0x35, 0x83, 0xef, 0x19, 0x83, 0x5f, 0x19, 0x83, 0xeb, 0x8c, 0xc1,
0x2a, 0x63, 0xf0, 0x37, 0x63, 0xf0, 0x2f, 0x63, 0xe4, 0x36, 0x63, 0xf0, 0x73, 0xc3, 0xc8, 0x6a,
0xc3, 0xc8, 0xcd, 0x86, 0x91, 0xb1, 0xad, 0x9f, 0xc6, 0xd1, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
0xab, 0x96, 0x85, 0x85, 0x86, 0x02, 0x00, 0x00,
}

@ -8,16 +8,14 @@ import (
"github.com/prometheus/prometheus/pkg/labels"
)
var labelNameBytes = []byte(model.MetricNameLabel)
// MetricNameFromLabelPairs extracts the metric name from a list of LabelPairs.
func MetricNameFromLabelPairs(labels []client.LabelPair) ([]byte, error) {
// MetricNameFromLabelAdapters extracts the metric name from a list of LabelPairs.
func MetricNameFromLabelAdapters(labels []client.LabelAdapter) (string, error) {
for _, label := range labels {
if label.Name.Equal(labelNameBytes) {
if label.Name == model.MetricNameLabel {
return label.Value, nil
}
}
return nil, fmt.Errorf("No metric name label")
return "", fmt.Errorf("No metric name label")
}
// MetricNameFromMetric extract the metric name from a model.Metric

@ -0,0 +1,26 @@
package flagext
import (
"flag"
"github.com/cortexproject/cortex/pkg/util"
"github.com/go-kit/kit/log/level"
)
type deprecatedFlag struct {
name string
}
func (deprecatedFlag) String() string {
return "deprecated"
}
func (d deprecatedFlag) Set(string) error {
level.Warn(util.Logger).Log("msg", "flag disabled", "flag", d.name)
return nil
}
// DeprecatedFlag logs a warning when you try to use it.
func DeprecatedFlag(f *flag.FlagSet, name, message string) {
f.Var(deprecatedFlag{name}, name, message)
}

@ -9,6 +9,6 @@ import "github.com/prometheus/common/model"
// function we use is prone to only change a few bits for similar metrics. We
// really want to make use of every change in the fingerprint to vary mutex
// selection.)
func HashFP(fp model.Fingerprint) uint {
return uint(fp ^ (fp >> 32) ^ (fp >> 16))
func HashFP(fp model.Fingerprint) uint32 {
return uint32(fp ^ (fp >> 32) ^ (fp >> 16))
}

@ -44,8 +44,14 @@ func InitLogger(cfg *server.Config) {
panic(err)
}
Logger = l
cfg.Log = logging.GoKit(l)
// when use util.Logger, skip 3 stack frames.
Logger = log.With(l, "caller", log.Caller(3))
// cfg.Log wraps log function, skip 4 stack frames to get caller information.
// this works in go 1.12, but doesn't work in versions earlier.
// it will always shows the wrapper function generated by compiler
// marked <autogenerated> in old versions.
cfg.Log = logging.GoKit(log.With(l, "caller", log.Caller(4)))
}
// PrometheusLogger exposes Prometheus counters for each of go-kit's log levels.
@ -68,8 +74,8 @@ func NewPrometheusLogger(l logging.Level) (log.Logger, error) {
logger: logger,
}
// DefaultCaller must be the last wrapper
logger = log.With(logger, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller)
// return a Logger without caller information, shouldn't use directly
logger = log.With(logger, "ts", log.DefaultTimestampUTC)
return logger, nil
}

@ -3,8 +3,6 @@ package validation
import (
"flag"
"time"
"github.com/cortexproject/cortex/pkg/util/flagext"
)
// Limits describe all the limits for users; can be used to describe global default
@ -28,8 +26,10 @@ type Limits struct {
MaxSeriesPerMetric int `yaml:"max_series_per_metric"`
// Querier enforced limits.
MaxChunksPerQuery int `yaml:"max_chunks_per_query"`
MaxQueryLength time.Duration `yaml:"max_query_length"`
MaxChunksPerQuery int `yaml:"max_chunks_per_query"`
MaxQueryLength time.Duration `yaml:"max_query_length"`
MaxQueryParallelism int `yaml:"max_query_parallelism"`
CardinalityLimit int `yaml:"cardinality_limit"`
// Config for overrides, convenient if it goes here.
PerTenantOverrideConfig string
@ -55,6 +55,8 @@ func (l *Limits) RegisterFlags(f *flag.FlagSet) {
f.IntVar(&l.MaxChunksPerQuery, "store.query-chunk-limit", 2e6, "Maximum number of chunks that can be fetched in a single query.")
f.DurationVar(&l.MaxQueryLength, "store.max-query-length", 0, "Limit to length of chunk store queries, 0 to disable.")
f.IntVar(&l.MaxQueryParallelism, "querier.max-query-parallelism", 14, "Maximum number of queries will be scheduled in parallel by the frontend.")
f.IntVar(&l.CardinalityLimit, "store.cardinality-limit", 1e5, "Cardinality limit for index queries.")
f.StringVar(&l.PerTenantOverrideConfig, "limits.per-user-override-config", "", "File name of per-user overrides.")
f.DurationVar(&l.PerTenantOverridePeriod, "limits.per-user-override-period", 10*time.Second, "Period with this to reload the overrides.")
@ -65,7 +67,7 @@ func (l *Limits) UnmarshalYAML(unmarshal func(interface{}) error) error {
// We want to set c to the defaults and then overwrite it with the input.
// To make unmarshal fill the plain data struct rather than calling UnmarshalYAML
// again, we have to hide it using a type indirection. See prometheus/config.
flagext.DefaultValues(l)
*l = defaultLimits
type plain Limits
return unmarshal((*plain)(l))
}

@ -18,6 +18,12 @@ var overridesReloadSuccess = promauto.NewGauge(prometheus.GaugeOpts{
Help: "Whether the last overrides reload attempt was successful.",
})
// When we load YAML from disk, we want the various per-customer limits
// to default to any values specified on the command line, not default
// command line values. This global contains those values. I (Tom) cannot
// find a nicer way I'm afraid.
var defaultLimits Limits
// Overrides periodically fetch a set of per-user overrides, and provides convenience
// functions for fetching the correct value.
type Overrides struct {
@ -28,7 +34,12 @@ type Overrides struct {
}
// NewOverrides makes a new Overrides.
// We store the supplied limits in a global variable to ensure per-tenant limits
// are defaulted to those values. As such, the last call to NewOverrides will
// become the new global defaults.
func NewOverrides(defaults Limits) (*Overrides, error) {
defaultLimits = defaults
if defaults.PerTenantOverrideConfig == "" {
level.Info(util.Logger).Log("msg", "per-tenant overides disabled")
return &Overrides{
@ -242,9 +253,24 @@ func (o *Overrides) MaxQueryLength(userID string) time.Duration {
})
}
// MaxQueryParallelism returns the limit to the number of sub-queries the
// frontend will process in parallel.
func (o *Overrides) MaxQueryParallelism(userID string) int {
return o.getInt(userID, func(l *Limits) int {
return l.MaxQueryParallelism
})
}
// EnforceMetricName whether to enforce the presence of a metric name.
func (o *Overrides) EnforceMetricName(userID string) bool {
return o.getBool(userID, func(l *Limits) bool {
return l.EnforceMetricName
})
}
// CardinalityLimit whether to enforce the presence of a metric name.
func (o *Overrides) CardinalityLimit(userID string) int {
return o.getInt(userID, func(l *Limits) int {
return l.CardinalityLimit
})
}

@ -22,6 +22,9 @@ const (
errTooOld = "sample for '%s' has timestamp too old: %d"
errTooNew = "sample for '%s' has timestamp too new: %d"
// ErrQueryTooLong is used in chunk store and query frontend.
ErrQueryTooLong = "invalid query, length > limit (%s > %s)"
greaterThanMaxSampleAge = "greater_than_max_sample_age"
maxLabelNamesPerSeries = "max_label_names_per_series"
tooFarInFuture = "too_far_in_future"
@ -48,7 +51,7 @@ func init() {
}
// ValidateSample returns an err if the sample is invalid.
func (cfg *Overrides) ValidateSample(userID string, metricName []byte, s client.Sample) error {
func (cfg *Overrides) ValidateSample(userID string, metricName string, s client.Sample) error {
if cfg.RejectOldSamples(userID) && model.Time(s.TimestampMs) < model.Now().Add(-cfg.RejectOldSamplesMaxAge(userID)) {
DiscardedSamples.WithLabelValues(greaterThanMaxSampleAge, userID).Inc()
return httpgrpc.Errorf(http.StatusBadRequest, errTooOld, metricName, model.Time(s.TimestampMs))
@ -63,8 +66,8 @@ func (cfg *Overrides) ValidateSample(userID string, metricName []byte, s client.
}
// ValidateLabels returns an err if the labels are invalid.
func (cfg *Overrides) ValidateLabels(userID string, ls []client.LabelPair) error {
metricName, err := extract.MetricNameFromLabelPairs(ls)
func (cfg *Overrides) ValidateLabels(userID string, ls []client.LabelAdapter) error {
metricName, err := extract.MetricNameFromLabelAdapters(ls)
if cfg.EnforceMetricName(userID) {
if err != nil {
return httpgrpc.Errorf(http.StatusBadRequest, errMissingMetricName)
@ -78,7 +81,7 @@ func (cfg *Overrides) ValidateLabels(userID string, ls []client.LabelPair) error
numLabelNames := len(ls)
if numLabelNames > cfg.MaxLabelNamesPerSeries(userID) {
DiscardedSamples.WithLabelValues(maxLabelNamesPerSeries, userID).Inc()
return httpgrpc.Errorf(http.StatusBadRequest, errTooManyLabels, client.FromLabelPairs(ls).String(), numLabelNames, cfg.MaxLabelNamesPerSeries(userID))
return httpgrpc.Errorf(http.StatusBadRequest, errTooManyLabels, client.FromLabelAdaptersToMetric(ls).String(), numLabelNames, cfg.MaxLabelNamesPerSeries(userID))
}
maxLabelNameLength := cfg.MaxLabelNameLength(userID)
@ -102,7 +105,7 @@ func (cfg *Overrides) ValidateLabels(userID string, ls []client.LabelPair) error
}
if errTemplate != "" {
DiscardedSamples.WithLabelValues(reason, userID).Inc()
return httpgrpc.Errorf(http.StatusBadRequest, errTemplate, cause, client.FromLabelPairs(ls).String())
return httpgrpc.Errorf(http.StatusBadRequest, errTemplate, cause, client.FromLabelAdaptersToMetric(ls).String())
}
}
return nil

Loading…
Cancel
Save