From b5c496d374d117ca687e5b8b44bbefd474dbdd6f Mon Sep 17 00:00:00 2001 From: Danny Kopping Date: Fri, 3 Jun 2022 09:11:52 +0200 Subject: [PATCH 01/11] Adding cache statistics Signed-off-by: Danny Kopping --- pkg/logqlmodel/stats/context.go | 117 +++ pkg/logqlmodel/stats/stats.pb.go | 920 ++++++++++++++++++++++-- pkg/logqlmodel/stats/stats.proto | 27 + pkg/querier/queryrange/roundtrip.go | 3 +- pkg/storage/chunk/cache/cache.go | 11 +- pkg/storage/chunk/cache/cache_gen.go | 6 + pkg/storage/chunk/cache/fifo_cache.go | 11 +- pkg/storage/chunk/cache/instrumented.go | 15 +- pkg/storage/chunk/cache/memcached.go | 23 +- pkg/storage/chunk/cache/mock.go | 6 + pkg/storage/chunk/cache/redis_cache.go | 21 +- pkg/storage/chunk/cache/snappy.go | 6 + pkg/storage/chunk/cache/tiered.go | 10 +- pkg/storage/store.go | 6 +- 14 files changed, 1077 insertions(+), 105 deletions(-) diff --git a/pkg/logqlmodel/stats/context.go b/pkg/logqlmodel/stats/context.go index 1d23f76ef3216..5315e378e64a8 100644 --- a/pkg/logqlmodel/stats/context.go +++ b/pkg/logqlmodel/stats/context.go @@ -43,6 +43,7 @@ const ( type Context struct { querier Querier ingester Ingester + caches Caches // store is the store statistics collected across the query path store Store @@ -52,6 +53,15 @@ type Context struct { mtx sync.Mutex } +type CacheType string + +const ( + ChunkCache CacheType = "chunk" + IndexCache = "index" + ResultCache = "result" + WriteDedupeCache = "write-dedupe" +) + // NewContext creates a new statistics context func NewContext(ctx context.Context) (*Context, context.Context) { contextData := &Context{} @@ -79,6 +89,15 @@ func (c *Context) Ingester() Ingester { } } +// Caches returns the cache statistics accumulated so far. +func (c *Context) Caches() Caches { + return Caches{ + Chunk: c.caches.Chunk, + Index: c.caches.Index, + Result: c.caches.Result, + } +} + // Reset clears the statistics. func (c *Context) Reset() { c.mtx.Lock() @@ -88,6 +107,7 @@ func (c *Context) Reset() { c.querier.Reset() c.ingester.Reset() c.result.Reset() + c.caches.Reset() } // Result calculates the summary based on store and ingester data. @@ -99,6 +119,7 @@ func (c *Context) Result(execTime time.Duration, queueTime time.Duration, totalE Store: c.store, }, Ingester: c.ingester, + Caches: c.caches, }) r.ComputeSummary(execTime, queueTime, totalEntriesReturned) @@ -168,12 +189,27 @@ func (i *Ingester) Merge(m Ingester) { i.TotalReached += m.TotalReached } +func (c *Caches) Merge(m Caches) { + c.Chunk.Merge(m.Chunk) + c.Index.Merge(m.Index) + c.Result.Merge(m.Result) +} + +func (c *Cache) Merge(m Cache) { + c.EntriesFound += m.EntriesFound + c.EntriesRequested += m.EntriesRequested + c.EntriesStored += m.EntriesStored + c.Requests += m.Requests + c.BytesTransferred += m.BytesTransferred +} + // Merge merges two results of statistics. // This will increase the total number of Subqueries. func (r *Result) Merge(m Result) { r.Summary.Subqueries++ r.Querier.Merge(m.Querier) r.Ingester.Merge(m.Ingester) + r.Caches.Merge(m.Caches) r.ComputeSummary(ConvertSecondsToNanoseconds(r.Summary.ExecTime+m.Summary.ExecTime), ConvertSecondsToNanoseconds(r.Summary.QueueTime+m.Summary.QueueTime), int(r.Summary.TotalEntriesReturned)) } @@ -257,6 +293,66 @@ func (c *Context) AddChunksRef(i int64) { atomic.AddInt64(&c.store.TotalChunksRef, i) } +func (c *Context) AddCacheEntriesFound(t CacheType, i int) { + stats := c.getCacheStatsByType(t) + if stats == nil { + return + } + + atomic.AddInt32(&stats.EntriesFound, int32(i)) +} + +func (c *Context) AddCacheEntriesRequested(t CacheType, i int) { + stats := c.getCacheStatsByType(t) + if stats == nil { + return + } + + atomic.AddInt32(&stats.EntriesRequested, int32(i)) +} + +func (c *Context) AddCacheEntriesStored(t CacheType, i int) { + stats := c.getCacheStatsByType(t) + if stats == nil { + return + } + + atomic.AddInt32(&stats.EntriesStored, int32(i)) +} + +func (c *Context) AddCacheBytesTransferred(t CacheType, i int) { + stats := c.getCacheStatsByType(t) + if stats == nil { + return + } + + atomic.AddInt64(&stats.BytesTransferred, int64(i)) +} + +func (c *Context) AddCacheRequest(t CacheType, i int) { + stats := c.getCacheStatsByType(t) + if stats == nil { + return + } + + atomic.AddInt32(&stats.Requests, int32(i)) +} + +func (c *Context) getCacheStatsByType(t CacheType) *Cache { + var stats *Cache + switch t { + case ChunkCache: + stats = &c.caches.Chunk + case IndexCache: + stats = &c.caches.Index + case ResultCache: + stats = &c.caches.Result + default: + return nil + } + return stats +} + // Log logs a query statistics result. func (r Result) Log(log log.Logger) { _ = log.Log( @@ -284,6 +380,7 @@ func (r Result) Log(log log.Logger) { "Querier.CompressedBytes", humanize.Bytes(uint64(r.Querier.Store.Chunk.CompressedBytes)), "Querier.TotalDuplicates", r.Querier.Store.Chunk.TotalDuplicates, ) + r.Caches.Log(log) r.Summary.Log(log) } @@ -297,3 +394,23 @@ func (s Summary) Log(log log.Logger) { "Summary.QueueTime", ConvertSecondsToNanoseconds(s.QueueTime), ) } + +func (c Caches) Log(log log.Logger) { + _ = log.Log( + "Cache.Chunk.Requests", c.Chunk.Requests, + "Cache.Chunk.EntriesRequested", c.Chunk.EntriesRequested, + "Cache.Chunk.EntriesFound", c.Chunk.EntriesFound, + "Cache.Chunk.EntriesStored", c.Chunk.EntriesStored, + "Cache.Chunk.BytesTransferred", humanize.Bytes(uint64(c.Chunk.BytesTransferred)), + "Cache.Index.Requests", c.Index.Requests, + "Cache.Index.EntriesRequested", c.Index.EntriesRequested, + "Cache.Index.EntriesFound", c.Index.EntriesFound, + "Cache.Index.EntriesStored", c.Index.EntriesStored, + "Cache.Index.BytesTransferred", humanize.Bytes(uint64(c.Index.BytesTransferred)), + "Cache.Result.Requests", c.Result.Requests, + "Cache.Result.EntriesRequested", c.Result.EntriesRequested, + "Cache.Result.EntriesFound", c.Result.EntriesFound, + "Cache.Result.EntriesStored", c.Result.EntriesStored, + "Cache.Result.BytesTransferred", humanize.Bytes(uint64(c.Result.BytesTransferred)), + ) +} diff --git a/pkg/logqlmodel/stats/stats.pb.go b/pkg/logqlmodel/stats/stats.pb.go index a8748ebe9ef52..75b9102070984 100644 --- a/pkg/logqlmodel/stats/stats.pb.go +++ b/pkg/logqlmodel/stats/stats.pb.go @@ -31,6 +31,7 @@ type Result struct { Summary Summary `protobuf:"bytes,1,opt,name=summary,proto3" json:"summary"` Querier Querier `protobuf:"bytes,2,opt,name=querier,proto3" json:"querier"` Ingester Ingester `protobuf:"bytes,3,opt,name=ingester,proto3" json:"ingester"` + Caches Caches `protobuf:"bytes,4,opt,name=caches,proto3" json:"cache"` } func (m *Result) Reset() { *m = Result{} } @@ -86,6 +87,72 @@ func (m *Result) GetIngester() Ingester { return Ingester{} } +func (m *Result) GetCaches() Caches { + if m != nil { + return m.Caches + } + return Caches{} +} + +type Caches struct { + Chunk Cache `protobuf:"bytes,1,opt,name=chunk,proto3" json:"chunk"` + Index Cache `protobuf:"bytes,2,opt,name=index,proto3" json:"index"` + Result Cache `protobuf:"bytes,3,opt,name=result,proto3" json:"result"` +} + +func (m *Caches) Reset() { *m = Caches{} } +func (*Caches) ProtoMessage() {} +func (*Caches) Descriptor() ([]byte, []int) { + return fileDescriptor_6cdfe5d2aea33ebb, []int{1} +} +func (m *Caches) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Caches) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Caches.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Caches) XXX_Merge(src proto.Message) { + xxx_messageInfo_Caches.Merge(m, src) +} +func (m *Caches) XXX_Size() int { + return m.Size() +} +func (m *Caches) XXX_DiscardUnknown() { + xxx_messageInfo_Caches.DiscardUnknown(m) +} + +var xxx_messageInfo_Caches proto.InternalMessageInfo + +func (m *Caches) GetChunk() Cache { + if m != nil { + return m.Chunk + } + return Cache{} +} + +func (m *Caches) GetIndex() Cache { + if m != nil { + return m.Index + } + return Cache{} +} + +func (m *Caches) GetResult() Cache { + if m != nil { + return m.Result + } + return Cache{} +} + // Summary is the summary of a query statistics. type Summary struct { // Total bytes processed per second. @@ -113,7 +180,7 @@ type Summary struct { func (m *Summary) Reset() { *m = Summary{} } func (*Summary) ProtoMessage() {} func (*Summary) Descriptor() ([]byte, []int) { - return fileDescriptor_6cdfe5d2aea33ebb, []int{1} + return fileDescriptor_6cdfe5d2aea33ebb, []int{2} } func (m *Summary) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -205,7 +272,7 @@ type Querier struct { func (m *Querier) Reset() { *m = Querier{} } func (*Querier) ProtoMessage() {} func (*Querier) Descriptor() ([]byte, []int) { - return fileDescriptor_6cdfe5d2aea33ebb, []int{2} + return fileDescriptor_6cdfe5d2aea33ebb, []int{3} } func (m *Querier) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -256,7 +323,7 @@ type Ingester struct { func (m *Ingester) Reset() { *m = Ingester{} } func (*Ingester) ProtoMessage() {} func (*Ingester) Descriptor() ([]byte, []int) { - return fileDescriptor_6cdfe5d2aea33ebb, []int{3} + return fileDescriptor_6cdfe5d2aea33ebb, []int{4} } func (m *Ingester) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -333,7 +400,7 @@ type Store struct { func (m *Store) Reset() { *m = Store{} } func (*Store) ProtoMessage() {} func (*Store) Descriptor() ([]byte, []int) { - return fileDescriptor_6cdfe5d2aea33ebb, []int{4} + return fileDescriptor_6cdfe5d2aea33ebb, []int{5} } func (m *Store) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -408,7 +475,7 @@ type Chunk struct { func (m *Chunk) Reset() { *m = Chunk{} } func (*Chunk) ProtoMessage() {} func (*Chunk) Descriptor() ([]byte, []int) { - return fileDescriptor_6cdfe5d2aea33ebb, []int{5} + return fileDescriptor_6cdfe5d2aea33ebb, []int{6} } func (m *Chunk) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -479,67 +546,154 @@ func (m *Chunk) GetTotalDuplicates() int64 { return 0 } +type Cache struct { + EntriesFound int32 `protobuf:"varint,1,opt,name=entriesFound,proto3" json:"entriesFound"` + EntriesRequested int32 `protobuf:"varint,2,opt,name=entriesRequested,proto3" json:"entriesRequested"` + EntriesStored int32 `protobuf:"varint,3,opt,name=entriesStored,proto3" json:"entriesStored"` + BytesTransferred int64 `protobuf:"varint,4,opt,name=bytesTransferred,proto3" json:"bytesTransferred"` + Requests int32 `protobuf:"varint,5,opt,name=requests,proto3" json:"requests"` +} + +func (m *Cache) Reset() { *m = Cache{} } +func (*Cache) ProtoMessage() {} +func (*Cache) Descriptor() ([]byte, []int) { + return fileDescriptor_6cdfe5d2aea33ebb, []int{7} +} +func (m *Cache) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Cache) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Cache.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Cache) XXX_Merge(src proto.Message) { + xxx_messageInfo_Cache.Merge(m, src) +} +func (m *Cache) XXX_Size() int { + return m.Size() +} +func (m *Cache) XXX_DiscardUnknown() { + xxx_messageInfo_Cache.DiscardUnknown(m) +} + +var xxx_messageInfo_Cache proto.InternalMessageInfo + +func (m *Cache) GetEntriesFound() int32 { + if m != nil { + return m.EntriesFound + } + return 0 +} + +func (m *Cache) GetEntriesRequested() int32 { + if m != nil { + return m.EntriesRequested + } + return 0 +} + +func (m *Cache) GetEntriesStored() int32 { + if m != nil { + return m.EntriesStored + } + return 0 +} + +func (m *Cache) GetBytesTransferred() int64 { + if m != nil { + return m.BytesTransferred + } + return 0 +} + +func (m *Cache) GetRequests() int32 { + if m != nil { + return m.Requests + } + return 0 +} + func init() { proto.RegisterType((*Result)(nil), "stats.Result") + proto.RegisterType((*Caches)(nil), "stats.Caches") proto.RegisterType((*Summary)(nil), "stats.Summary") proto.RegisterType((*Querier)(nil), "stats.Querier") proto.RegisterType((*Ingester)(nil), "stats.Ingester") proto.RegisterType((*Store)(nil), "stats.Store") proto.RegisterType((*Chunk)(nil), "stats.Chunk") + proto.RegisterType((*Cache)(nil), "stats.Cache") } func init() { proto.RegisterFile("pkg/logqlmodel/stats/stats.proto", fileDescriptor_6cdfe5d2aea33ebb) } var fileDescriptor_6cdfe5d2aea33ebb = []byte{ - // 759 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x55, 0x4d, 0x6f, 0xd3, 0x4c, - 0x10, 0x8e, 0x93, 0xe6, 0xa3, 0xfb, 0xf6, 0xeb, 0xdd, 0x52, 0x6a, 0x40, 0xb2, 0xab, 0x9c, 0x2a, - 0x01, 0x89, 0xf8, 0xb8, 0x80, 0xe8, 0xc5, 0x2d, 0x48, 0x95, 0x8a, 0x28, 0x53, 0xb8, 0x70, 0x73, - 0x9c, 0x6d, 0x12, 0xd5, 0xf1, 0xa6, 0xf6, 0x5a, 0xd0, 0x1b, 0x37, 0x8e, 0xf0, 0x1b, 0x38, 0x71, - 0xe1, 0x27, 0x70, 0xef, 0xb1, 0xc7, 0x9e, 0x2c, 0x9a, 0x5e, 0x90, 0x4f, 0xfd, 0x09, 0xc8, 0xb3, - 0x8e, 0x1d, 0x3b, 0x8e, 0xc4, 0x25, 0x99, 0x79, 0x9e, 0x79, 0x66, 0xd6, 0x33, 0xb3, 0x5a, 0xb2, - 0x35, 0x3a, 0xe9, 0xb5, 0x6d, 0xde, 0x3b, 0xb5, 0x87, 0xbc, 0xcb, 0xec, 0xb6, 0x27, 0x4c, 0xe1, - 0xc9, 0xdf, 0xd6, 0xc8, 0xe5, 0x82, 0xd3, 0x2a, 0x3a, 0x77, 0x1f, 0xf6, 0x06, 0xa2, 0xef, 0x77, - 0x5a, 0x16, 0x1f, 0xb6, 0x7b, 0xbc, 0xc7, 0xdb, 0xc8, 0x76, 0xfc, 0x63, 0xf4, 0xd0, 0x41, 0x4b, - 0xaa, 0x9a, 0xbf, 0x14, 0x52, 0x03, 0xe6, 0xf9, 0xb6, 0xa0, 0xcf, 0x48, 0xdd, 0xf3, 0x87, 0x43, - 0xd3, 0x3d, 0x53, 0x95, 0x2d, 0x65, 0xfb, 0xbf, 0xc7, 0x2b, 0x2d, 0x99, 0xff, 0x48, 0xa2, 0xc6, - 0xea, 0x79, 0xa0, 0x97, 0xc2, 0x40, 0x9f, 0x84, 0xc1, 0xc4, 0x88, 0xa4, 0xa7, 0x3e, 0x73, 0x07, - 0xcc, 0x55, 0xcb, 0x19, 0xe9, 0x5b, 0x89, 0xa6, 0xd2, 0x38, 0x0c, 0x26, 0x06, 0xdd, 0x21, 0x8d, - 0x81, 0xd3, 0x63, 0x9e, 0x60, 0xae, 0x5a, 0x41, 0xed, 0x6a, 0xac, 0xdd, 0x8f, 0x61, 0x63, 0x2d, - 0x16, 0x27, 0x81, 0x90, 0x58, 0xcd, 0xef, 0x0b, 0xa4, 0x1e, 0x9f, 0x8f, 0xbe, 0x27, 0x9b, 0x9d, - 0x33, 0xc1, 0xbc, 0x43, 0x97, 0x5b, 0xcc, 0xf3, 0x58, 0xf7, 0x90, 0xb9, 0x47, 0xcc, 0xe2, 0x4e, - 0x17, 0x3f, 0xa8, 0x62, 0xdc, 0x0b, 0x03, 0x7d, 0x5e, 0x08, 0xcc, 0x23, 0xa2, 0xb4, 0xf6, 0xc0, - 0x29, 0x4c, 0x5b, 0x4e, 0xd3, 0xce, 0x09, 0x81, 0x79, 0x04, 0xdd, 0x27, 0xeb, 0x82, 0x0b, 0xd3, - 0x36, 0x32, 0x65, 0xb1, 0x07, 0x15, 0x63, 0x33, 0x0c, 0xf4, 0x22, 0x1a, 0x8a, 0xc0, 0x24, 0xd5, - 0x41, 0xa6, 0x94, 0xba, 0x90, 0x4b, 0x95, 0xa5, 0xa1, 0x08, 0xa4, 0xdb, 0xa4, 0xc1, 0x3e, 0x31, - 0xeb, 0xdd, 0x60, 0xc8, 0xd4, 0xea, 0x96, 0xb2, 0xad, 0x18, 0x4b, 0x51, 0xe7, 0x27, 0x18, 0x24, - 0x16, 0xbd, 0x4f, 0x16, 0x4f, 0x7d, 0xe6, 0x33, 0x0c, 0xad, 0x61, 0xe8, 0x72, 0x18, 0xe8, 0x29, - 0x08, 0xa9, 0x49, 0x5b, 0x84, 0x78, 0x7e, 0x47, 0xce, 0xdc, 0x53, 0xeb, 0x78, 0xb0, 0x95, 0x30, - 0xd0, 0xa7, 0x50, 0x98, 0xb2, 0xe9, 0x01, 0xb9, 0x85, 0xa7, 0x7b, 0xe9, 0x08, 0xe4, 0x98, 0xf0, - 0x5d, 0x87, 0x75, 0xd5, 0x06, 0x2a, 0xd5, 0x30, 0xd0, 0x0b, 0x79, 0x28, 0x44, 0x9b, 0x2f, 0x48, - 0x3d, 0x5e, 0x44, 0xfa, 0x88, 0x54, 0x3d, 0xc1, 0x5d, 0x16, 0xaf, 0xf8, 0xd2, 0x64, 0xc5, 0x23, - 0xcc, 0x58, 0x8e, 0x17, 0x4d, 0x86, 0x80, 0xfc, 0x6b, 0xfe, 0x2c, 0x93, 0xc6, 0x64, 0x17, 0xe9, - 0x53, 0xb2, 0x84, 0x25, 0x80, 0x99, 0x56, 0x9f, 0xc9, 0xc5, 0xaa, 0x1a, 0x6b, 0x61, 0xa0, 0x67, - 0x70, 0xc8, 0x78, 0xf4, 0x15, 0xa1, 0xe8, 0xef, 0xf6, 0x7d, 0xe7, 0xc4, 0x7b, 0x6d, 0x0a, 0xd4, - 0xca, 0xed, 0xb9, 0x1d, 0x06, 0x7a, 0x01, 0x0b, 0x05, 0x58, 0x52, 0xdd, 0x40, 0xdf, 0x8b, 0x97, - 0x25, 0xad, 0x1e, 0xe3, 0x90, 0xf1, 0xe8, 0x73, 0xb2, 0x92, 0x8e, 0xfa, 0x88, 0x39, 0x22, 0xde, - 0x0c, 0x1a, 0x06, 0x7a, 0x8e, 0x81, 0x9c, 0x9f, 0xf6, 0xab, 0xfa, 0xcf, 0xfd, 0xfa, 0x5a, 0x26, - 0x55, 0xe4, 0x93, 0xc2, 0xf2, 0x23, 0x80, 0x1d, 0xc7, 0xf7, 0x30, 0x2d, 0x9c, 0x30, 0x90, 0xf3, - 0xe9, 0x1b, 0xb2, 0x31, 0x85, 0xec, 0xf1, 0x8f, 0x8e, 0xcd, 0xcd, 0x6e, 0xd2, 0xb5, 0x3b, 0x61, - 0xa0, 0x17, 0x07, 0x40, 0x31, 0x1c, 0xcd, 0xc0, 0xca, 0x60, 0xb8, 0xb8, 0x95, 0x74, 0x06, 0xb3, - 0x2c, 0x14, 0x60, 0x51, 0x47, 0x10, 0xc5, 0x26, 0xa6, 0x1d, 0xc1, 0x7a, 0x69, 0x47, 0x30, 0x04, - 0xe4, 0x5f, 0xf3, 0x4b, 0x85, 0x54, 0x91, 0x8f, 0x3a, 0xd2, 0x67, 0x66, 0x57, 0x06, 0x47, 0x97, - 0x78, 0x7a, 0x14, 0x59, 0x06, 0x72, 0x7e, 0x46, 0x8b, 0x03, 0xc2, 0x99, 0xe4, 0xb5, 0xc8, 0x40, - 0xce, 0xa7, 0xbb, 0xe4, 0xff, 0x2e, 0xb3, 0xf8, 0x70, 0xe4, 0xe2, 0x35, 0x97, 0xa5, 0x6b, 0x28, - 0xdf, 0x08, 0x03, 0x7d, 0x96, 0x84, 0x59, 0x28, 0x9f, 0x44, 0x9e, 0xa1, 0x5e, 0x9c, 0x44, 0x1e, - 0x63, 0x16, 0xa2, 0x3b, 0x64, 0x35, 0x7f, 0x0e, 0x79, 0xa9, 0xd7, 0xc3, 0x40, 0xcf, 0x53, 0x90, - 0x07, 0x22, 0x39, 0x8e, 0x77, 0xcf, 0x1f, 0xd9, 0x03, 0xcb, 0x8c, 0xe4, 0x8b, 0xa9, 0x3c, 0x47, - 0x41, 0x1e, 0x30, 0x3a, 0x17, 0x57, 0x5a, 0xe9, 0xf2, 0x4a, 0x2b, 0xdd, 0x5c, 0x69, 0xca, 0xe7, - 0xb1, 0xa6, 0xfc, 0x18, 0x6b, 0xca, 0xf9, 0x58, 0x53, 0x2e, 0xc6, 0x9a, 0xf2, 0x7b, 0xac, 0x29, - 0x7f, 0xc6, 0x5a, 0xe9, 0x66, 0xac, 0x29, 0xdf, 0xae, 0xb5, 0xd2, 0xc5, 0xb5, 0x56, 0xba, 0xbc, - 0xd6, 0x4a, 0x1f, 0x1e, 0x4c, 0xbf, 0xa9, 0xae, 0x79, 0x6c, 0x3a, 0x66, 0xdb, 0xe6, 0x27, 0x83, - 0x76, 0xd1, 0xa3, 0xdc, 0xa9, 0xe1, 0xcb, 0xfa, 0xe4, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x9a, - 0x84, 0xb3, 0x79, 0xb3, 0x07, 0x00, 0x00, + // 924 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0x4f, 0x8f, 0xdb, 0x44, + 0x14, 0x8f, 0x93, 0x75, 0xb2, 0x1d, 0xf6, 0x5f, 0xa7, 0x2d, 0x0d, 0x20, 0xd9, 0xab, 0x9c, 0x56, + 0x02, 0x36, 0xe2, 0x8f, 0x84, 0x40, 0x54, 0x42, 0xde, 0x52, 0x69, 0xa5, 0x22, 0xca, 0xdb, 0x72, + 0xe1, 0xe6, 0x38, 0xb3, 0x59, 0x6b, 0x1d, 0xcf, 0x66, 0x6c, 0x8b, 0xf6, 0xc6, 0x8d, 0x23, 0x7c, + 0x06, 0xd4, 0x03, 0x17, 0xbe, 0x47, 0x8f, 0x7b, 0xec, 0xc9, 0x62, 0xb3, 0x17, 0xe4, 0x53, 0x25, + 0xbe, 0x00, 0x9a, 0x37, 0x13, 0xdb, 0xe3, 0x38, 0x12, 0x97, 0xcc, 0xbc, 0xdf, 0xef, 0xfd, 0xe6, + 0xcd, 0x9f, 0xf7, 0x5e, 0x4c, 0x0e, 0xaf, 0x2e, 0x67, 0xe3, 0x88, 0xcf, 0x16, 0xd1, 0x9c, 0x4f, + 0x59, 0x34, 0x4e, 0x52, 0x3f, 0x4d, 0xd4, 0xef, 0xf1, 0x95, 0xe0, 0x29, 0xa7, 0x36, 0x1a, 0xef, + 0x7f, 0x3c, 0x0b, 0xd3, 0x8b, 0x6c, 0x72, 0x1c, 0xf0, 0xf9, 0x78, 0xc6, 0x67, 0x7c, 0x8c, 0xec, + 0x24, 0x3b, 0x47, 0x0b, 0x0d, 0x9c, 0x29, 0xd5, 0xe8, 0x5f, 0x8b, 0xf4, 0x81, 0x25, 0x59, 0x94, + 0xd2, 0x2f, 0xc9, 0x20, 0xc9, 0xe6, 0x73, 0x5f, 0xbc, 0x1c, 0x5a, 0x87, 0xd6, 0xd1, 0x3b, 0x9f, + 0xee, 0x1d, 0xab, 0xf5, 0xcf, 0x14, 0xea, 0xed, 0xbf, 0xce, 0xdd, 0x4e, 0x91, 0xbb, 0x2b, 0x37, + 0x58, 0x4d, 0xa4, 0x74, 0x91, 0x31, 0x11, 0x32, 0x31, 0xec, 0x1a, 0xd2, 0x1f, 0x14, 0x5a, 0x49, + 0xb5, 0x1b, 0xac, 0x26, 0xf4, 0x11, 0xd9, 0x0e, 0xe3, 0x19, 0x4b, 0x52, 0x26, 0x86, 0x3d, 0xd4, + 0xee, 0x6b, 0xed, 0xa9, 0x86, 0xbd, 0x03, 0x2d, 0x2e, 0x1d, 0xa1, 0x9c, 0xd1, 0xcf, 0x49, 0x3f, + 0xf0, 0x83, 0x0b, 0x96, 0x0c, 0xb7, 0x50, 0xbc, 0xab, 0xc5, 0x27, 0x08, 0x7a, 0xbb, 0x5a, 0x6a, + 0xa3, 0x13, 0x68, 0xdf, 0xd1, 0x2b, 0x8b, 0xf4, 0x95, 0x07, 0xfd, 0x84, 0xd8, 0xc1, 0x45, 0x16, + 0x5f, 0xea, 0x33, 0xef, 0xd4, 0xf5, 0x35, 0xb9, 0x74, 0x01, 0x35, 0x48, 0x49, 0x18, 0x4f, 0xd9, + 0x0b, 0x7d, 0xd6, 0x0d, 0x12, 0x74, 0x01, 0x35, 0xc8, 0x6d, 0x0a, 0xbc, 0x65, 0x7d, 0x46, 0x53, + 0xb3, 0xa7, 0x35, 0xda, 0x07, 0xf4, 0x38, 0xfa, 0x63, 0x8b, 0x0c, 0xf4, 0xe5, 0xd3, 0x1f, 0xc9, + 0xc3, 0xc9, 0xcb, 0x94, 0x25, 0xcf, 0x04, 0x0f, 0x58, 0x92, 0xb0, 0xe9, 0x33, 0x26, 0xce, 0x58, + 0xc0, 0xe3, 0x29, 0xee, 0xbc, 0xe7, 0x7d, 0x50, 0xe4, 0xee, 0x26, 0x17, 0xd8, 0x44, 0xc8, 0x65, + 0xa3, 0x30, 0x6e, 0x5d, 0xb6, 0x5b, 0x2d, 0xbb, 0xc1, 0x05, 0x36, 0x11, 0xf4, 0x94, 0xdc, 0x4b, + 0x79, 0xea, 0x47, 0x9e, 0x11, 0x16, 0x0f, 0xdf, 0xf3, 0x1e, 0x16, 0xb9, 0xdb, 0x46, 0x43, 0x1b, + 0x58, 0x2e, 0xf5, 0xd4, 0x08, 0x85, 0xcf, 0x5d, 0x5f, 0xca, 0xa4, 0xa1, 0x0d, 0xa4, 0x47, 0x64, + 0x9b, 0xbd, 0x60, 0xc1, 0xf3, 0x70, 0xce, 0x86, 0xf6, 0xa1, 0x75, 0x64, 0x79, 0x3b, 0x32, 0xad, + 0x56, 0x18, 0x94, 0x33, 0xfa, 0x21, 0xb9, 0xb3, 0xc8, 0x58, 0xc6, 0xd0, 0xb5, 0x8f, 0xae, 0xbb, + 0x45, 0xee, 0x56, 0x20, 0x54, 0x53, 0x7a, 0x4c, 0x48, 0x92, 0x4d, 0x54, 0x42, 0x27, 0xc3, 0x01, + 0x6e, 0x6c, 0xaf, 0xc8, 0xdd, 0x1a, 0x0a, 0xb5, 0x39, 0x7d, 0x4a, 0xee, 0xe3, 0xee, 0xbe, 0x8d, + 0x53, 0xe4, 0x58, 0x9a, 0x89, 0x98, 0x4d, 0x87, 0xdb, 0xa8, 0x1c, 0x16, 0xb9, 0xdb, 0xca, 0x43, + 0x2b, 0x3a, 0xfa, 0x9a, 0x0c, 0x74, 0x95, 0xc9, 0xc4, 0x4c, 0x52, 0x2e, 0x58, 0x23, 0x97, 0xcf, + 0x24, 0x56, 0x25, 0x26, 0xba, 0x80, 0x1a, 0x46, 0x7f, 0x75, 0xc9, 0xf6, 0x69, 0x55, 0x4c, 0x3b, + 0x18, 0x02, 0x98, 0x4c, 0x4b, 0x95, 0x58, 0xb6, 0x77, 0x50, 0xe4, 0xae, 0x81, 0x83, 0x61, 0xd1, + 0x27, 0x84, 0xa2, 0x7d, 0x22, 0x8b, 0x23, 0xf9, 0xce, 0x4f, 0x51, 0xab, 0xb2, 0xe7, 0xdd, 0x22, + 0x77, 0x5b, 0x58, 0x68, 0xc1, 0xca, 0xe8, 0x1e, 0xda, 0x89, 0x4e, 0x96, 0x2a, 0xba, 0xc6, 0xc1, + 0xb0, 0xe8, 0x57, 0x64, 0xaf, 0x7a, 0xea, 0x33, 0x16, 0xa7, 0x3a, 0x33, 0x68, 0x91, 0xbb, 0x0d, + 0x06, 0x1a, 0x76, 0x75, 0x5f, 0xf6, 0xff, 0xbe, 0xaf, 0xdf, 0xba, 0xc4, 0x46, 0xbe, 0x0c, 0xac, + 0x0e, 0x01, 0xec, 0x5c, 0xd7, 0x61, 0x15, 0xb8, 0x64, 0xa0, 0x61, 0xd3, 0xef, 0xc9, 0x83, 0x1a, + 0xf2, 0x98, 0xff, 0x1c, 0x47, 0xdc, 0x9f, 0x96, 0xb7, 0xf6, 0x5e, 0x91, 0xbb, 0xed, 0x0e, 0xd0, + 0x0e, 0xcb, 0x37, 0x08, 0x0c, 0x0c, 0x13, 0xb7, 0x57, 0xbd, 0xc1, 0x3a, 0x0b, 0x2d, 0x58, 0xd5, + 0x0d, 0xb7, 0xcc, 0x36, 0x25, 0xb1, 0xf6, 0x6e, 0x38, 0xfa, 0xb5, 0x47, 0x6c, 0xe4, 0xe5, 0x8d, + 0x5c, 0x30, 0x7f, 0xaa, 0x9c, 0x65, 0x11, 0xd7, 0x9f, 0xc2, 0x64, 0xa0, 0x61, 0x1b, 0x5a, 0x7c, + 0x20, 0x7c, 0x93, 0xa6, 0x16, 0x19, 0x68, 0xd8, 0xf4, 0x84, 0xdc, 0x9d, 0xb2, 0x80, 0xcf, 0xaf, + 0x04, 0x96, 0xb9, 0x0a, 0xdd, 0x47, 0xf9, 0x83, 0x22, 0x77, 0xd7, 0x49, 0x58, 0x87, 0x9a, 0x8b, + 0xa8, 0x3d, 0x0c, 0xda, 0x17, 0x51, 0xdb, 0x58, 0x87, 0xe8, 0x23, 0xb2, 0xdf, 0xdc, 0x87, 0x2a, + 0xea, 0x7b, 0x45, 0xee, 0x36, 0x29, 0x68, 0x02, 0x52, 0x8e, 0xcf, 0xfb, 0x38, 0xbb, 0x8a, 0xc2, + 0xc0, 0x97, 0xf2, 0x3b, 0x95, 0xbc, 0x41, 0x41, 0x13, 0x18, 0xbd, 0xea, 0x12, 0x1b, 0xff, 0x50, + 0x64, 0x29, 0x31, 0xd5, 0x26, 0x9e, 0xf0, 0x2c, 0x36, 0x0a, 0xb9, 0x8e, 0x83, 0x61, 0xd1, 0x6f, + 0xc8, 0x01, 0x5b, 0x35, 0x97, 0x45, 0x26, 0x5b, 0x82, 0x4a, 0x48, 0xdb, 0xbb, 0x5f, 0xe4, 0xee, + 0x1a, 0x07, 0x6b, 0x08, 0xfd, 0x82, 0xec, 0x6a, 0x0c, 0x6b, 0x44, 0x35, 0x7c, 0xdb, 0xbb, 0x5b, + 0xe4, 0xae, 0x49, 0x80, 0x69, 0xca, 0xd0, 0xf8, 0x0f, 0xf5, 0x5c, 0xf8, 0x71, 0x72, 0xce, 0x84, + 0x28, 0x3b, 0x3c, 0x86, 0x6e, 0x72, 0xb0, 0x86, 0xc8, 0xde, 0x2e, 0xd4, 0x3e, 0x54, 0xea, 0xd8, + 0xaa, 0xb7, 0xaf, 0x30, 0x28, 0x67, 0xde, 0xe4, 0xfa, 0xc6, 0xe9, 0xbc, 0xb9, 0x71, 0x3a, 0x6f, + 0x6f, 0x1c, 0xeb, 0x97, 0xa5, 0x63, 0xfd, 0xb9, 0x74, 0xac, 0xd7, 0x4b, 0xc7, 0xba, 0x5e, 0x3a, + 0xd6, 0xdf, 0x4b, 0xc7, 0xfa, 0x67, 0xe9, 0x74, 0xde, 0x2e, 0x1d, 0xeb, 0xf7, 0x5b, 0xa7, 0x73, + 0x7d, 0xeb, 0x74, 0xde, 0xdc, 0x3a, 0x9d, 0x9f, 0x3e, 0xaa, 0x7f, 0x57, 0x09, 0xff, 0xdc, 0x8f, + 0xfd, 0x71, 0xc4, 0x2f, 0xc3, 0x71, 0xdb, 0x87, 0xd9, 0xa4, 0x8f, 0x5f, 0x57, 0x9f, 0xfd, 0x17, + 0x00, 0x00, 0xff, 0xff, 0xaf, 0xcd, 0x69, 0x7f, 0xb7, 0x09, 0x00, 0x00, } func (this *Result) Equal(that interface{}) bool { @@ -570,6 +724,39 @@ func (this *Result) Equal(that interface{}) bool { if !this.Ingester.Equal(&that1.Ingester) { return false } + if !this.Caches.Equal(&that1.Caches) { + return false + } + return true +} +func (this *Caches) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*Caches) + if !ok { + that2, ok := that.(Caches) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if !this.Chunk.Equal(&that1.Chunk) { + return false + } + if !this.Index.Equal(&that1.Index) { + return false + } + if !this.Result.Equal(&that1.Result) { + return false + } return true } func (this *Summary) Equal(that interface{}) bool { @@ -749,15 +936,64 @@ func (this *Chunk) Equal(that interface{}) bool { } return true } +func (this *Cache) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*Cache) + if !ok { + that2, ok := that.(Cache) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.EntriesFound != that1.EntriesFound { + return false + } + if this.EntriesRequested != that1.EntriesRequested { + return false + } + if this.EntriesStored != that1.EntriesStored { + return false + } + if this.BytesTransferred != that1.BytesTransferred { + return false + } + if this.Requests != that1.Requests { + return false + } + return true +} func (this *Result) GoString() string { if this == nil { return "nil" } - s := make([]string, 0, 7) + s := make([]string, 0, 8) s = append(s, "&stats.Result{") s = append(s, "Summary: "+strings.Replace(this.Summary.GoString(), `&`, ``, 1)+",\n") s = append(s, "Querier: "+strings.Replace(this.Querier.GoString(), `&`, ``, 1)+",\n") s = append(s, "Ingester: "+strings.Replace(this.Ingester.GoString(), `&`, ``, 1)+",\n") + s = append(s, "Caches: "+strings.Replace(this.Caches.GoString(), `&`, ``, 1)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} +func (this *Caches) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 7) + s = append(s, "&stats.Caches{") + s = append(s, "Chunk: "+strings.Replace(this.Chunk.GoString(), `&`, ``, 1)+",\n") + s = append(s, "Index: "+strings.Replace(this.Index.GoString(), `&`, ``, 1)+",\n") + s = append(s, "Result: "+strings.Replace(this.Result.GoString(), `&`, ``, 1)+",\n") s = append(s, "}") return strings.Join(s, "") } @@ -830,6 +1066,20 @@ func (this *Chunk) GoString() string { s = append(s, "}") return strings.Join(s, "") } +func (this *Cache) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 9) + s = append(s, "&stats.Cache{") + s = append(s, "EntriesFound: "+fmt.Sprintf("%#v", this.EntriesFound)+",\n") + s = append(s, "EntriesRequested: "+fmt.Sprintf("%#v", this.EntriesRequested)+",\n") + s = append(s, "EntriesStored: "+fmt.Sprintf("%#v", this.EntriesStored)+",\n") + s = append(s, "BytesTransferred: "+fmt.Sprintf("%#v", this.BytesTransferred)+",\n") + s = append(s, "Requests: "+fmt.Sprintf("%#v", this.Requests)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} func valueToGoStringStats(v interface{}, typ string) string { rv := reflect.ValueOf(v) if rv.IsNil() { @@ -858,6 +1108,16 @@ func (m *Result) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + { + size, err := m.Caches.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintStats(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 { size, err := m.Ingester.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -891,6 +1151,59 @@ func (m *Result) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *Caches) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Caches) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Caches) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Result.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintStats(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + { + size, err := m.Index.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintStats(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.Chunk.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintStats(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *Summary) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1143,34 +1456,99 @@ func (m *Chunk) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func encodeVarintStats(dAtA []byte, offset int, v uint64) int { - offset -= sovStats(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ +func (m *Cache) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - dAtA[offset] = uint8(v) - return base + return dAtA[:n], nil } -func (m *Result) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.Summary.Size() - n += 1 + l + sovStats(uint64(l)) - l = m.Querier.Size() - n += 1 + l + sovStats(uint64(l)) - l = m.Ingester.Size() - n += 1 + l + sovStats(uint64(l)) - return n + +func (m *Cache) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *Summary) Size() (n int) { - if m == nil { +func (m *Cache) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Requests != 0 { + i = encodeVarintStats(dAtA, i, uint64(m.Requests)) + i-- + dAtA[i] = 0x28 + } + if m.BytesTransferred != 0 { + i = encodeVarintStats(dAtA, i, uint64(m.BytesTransferred)) + i-- + dAtA[i] = 0x20 + } + if m.EntriesStored != 0 { + i = encodeVarintStats(dAtA, i, uint64(m.EntriesStored)) + i-- + dAtA[i] = 0x18 + } + if m.EntriesRequested != 0 { + i = encodeVarintStats(dAtA, i, uint64(m.EntriesRequested)) + i-- + dAtA[i] = 0x10 + } + if m.EntriesFound != 0 { + i = encodeVarintStats(dAtA, i, uint64(m.EntriesFound)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintStats(dAtA []byte, offset int, v uint64) int { + offset -= sovStats(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Result) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Summary.Size() + n += 1 + l + sovStats(uint64(l)) + l = m.Querier.Size() + n += 1 + l + sovStats(uint64(l)) + l = m.Ingester.Size() + n += 1 + l + sovStats(uint64(l)) + l = m.Caches.Size() + n += 1 + l + sovStats(uint64(l)) + return n +} + +func (m *Caches) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Chunk.Size() + n += 1 + l + sovStats(uint64(l)) + l = m.Index.Size() + n += 1 + l + sovStats(uint64(l)) + l = m.Result.Size() + n += 1 + l + sovStats(uint64(l)) + return n +} + +func (m *Summary) Size() (n int) { + if m == nil { return 0 } var l int @@ -1283,6 +1661,30 @@ func (m *Chunk) Size() (n int) { return n } +func (m *Cache) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.EntriesFound != 0 { + n += 1 + sovStats(uint64(m.EntriesFound)) + } + if m.EntriesRequested != 0 { + n += 1 + sovStats(uint64(m.EntriesRequested)) + } + if m.EntriesStored != 0 { + n += 1 + sovStats(uint64(m.EntriesStored)) + } + if m.BytesTransferred != 0 { + n += 1 + sovStats(uint64(m.BytesTransferred)) + } + if m.Requests != 0 { + n += 1 + sovStats(uint64(m.Requests)) + } + return n +} + func sovStats(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -1297,6 +1699,19 @@ func (this *Result) String() string { `Summary:` + strings.Replace(strings.Replace(this.Summary.String(), "Summary", "Summary", 1), `&`, ``, 1) + `,`, `Querier:` + strings.Replace(strings.Replace(this.Querier.String(), "Querier", "Querier", 1), `&`, ``, 1) + `,`, `Ingester:` + strings.Replace(strings.Replace(this.Ingester.String(), "Ingester", "Ingester", 1), `&`, ``, 1) + `,`, + `Caches:` + strings.Replace(strings.Replace(this.Caches.String(), "Caches", "Caches", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *Caches) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&Caches{`, + `Chunk:` + strings.Replace(strings.Replace(this.Chunk.String(), "Cache", "Cache", 1), `&`, ``, 1) + `,`, + `Index:` + strings.Replace(strings.Replace(this.Index.String(), "Cache", "Cache", 1), `&`, ``, 1) + `,`, + `Result:` + strings.Replace(strings.Replace(this.Result.String(), "Cache", "Cache", 1), `&`, ``, 1) + `,`, `}`, }, "") return s @@ -1370,6 +1785,20 @@ func (this *Chunk) String() string { }, "") return s } +func (this *Cache) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&Cache{`, + `EntriesFound:` + fmt.Sprintf("%v", this.EntriesFound) + `,`, + `EntriesRequested:` + fmt.Sprintf("%v", this.EntriesRequested) + `,`, + `EntriesStored:` + fmt.Sprintf("%v", this.EntriesStored) + `,`, + `BytesTransferred:` + fmt.Sprintf("%v", this.BytesTransferred) + `,`, + `Requests:` + fmt.Sprintf("%v", this.Requests) + `,`, + `}`, + }, "") + return s +} func valueToStringStats(v interface{}) string { rv := reflect.ValueOf(v) if rv.IsNil() { @@ -1506,6 +1935,191 @@ func (m *Result) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Caches", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStats + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthStats + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthStats + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Caches.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipStats(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthStats + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthStats + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Caches) 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 ErrIntOverflowStats + } + 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: Caches: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Caches: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Chunk", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStats + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthStats + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthStats + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Chunk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStats + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthStats + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthStats + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Index.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStats + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthStats + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthStats + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Result.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipStats(dAtA[iNdEx:]) @@ -2277,6 +2891,154 @@ func (m *Chunk) Unmarshal(dAtA []byte) error { } return nil } +func (m *Cache) 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 ErrIntOverflowStats + } + 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: Cache: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Cache: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EntriesFound", wireType) + } + m.EntriesFound = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStats + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EntriesFound |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EntriesRequested", wireType) + } + m.EntriesRequested = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStats + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EntriesRequested |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EntriesStored", wireType) + } + m.EntriesStored = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStats + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EntriesStored |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BytesTransferred", wireType) + } + m.BytesTransferred = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStats + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.BytesTransferred |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Requests", wireType) + } + m.Requests = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStats + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Requests |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipStats(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthStats + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthStats + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipStats(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/pkg/logqlmodel/stats/stats.proto b/pkg/logqlmodel/stats/stats.proto index 657c8e2545d1a..27615021e1e8c 100644 --- a/pkg/logqlmodel/stats/stats.proto +++ b/pkg/logqlmodel/stats/stats.proto @@ -22,6 +22,25 @@ message Result { (gogoproto.nullable) = false, (gogoproto.jsontag) = "ingester" ]; + Caches caches = 4 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "cache" + ]; +} + +message Caches { + Cache chunk = 1 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "chunk" + ]; + Cache index = 2 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "index" + ]; + Cache result = 3 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "result" + ]; } // Summary is the summary of a query statistics. @@ -99,3 +118,11 @@ message Chunk { // Total duplicates found while processing. int64 totalDuplicates = 9 [(gogoproto.jsontag) = "totalDuplicates"]; } + +message Cache { + int32 entriesFound = 1 [(gogoproto.jsontag) = "entriesFound"]; + int32 entriesRequested = 2 [(gogoproto.jsontag) = "entriesRequested"]; + int32 entriesStored = 3 [(gogoproto.jsontag) = "entriesStored"]; + int64 bytesTransferred = 4 [(gogoproto.jsontag) = "bytesTransferred"]; + int32 requests = 5 [(gogoproto.jsontag) = "requests"]; +} diff --git a/pkg/querier/queryrange/roundtrip.go b/pkg/querier/queryrange/roundtrip.go index 23e042c819d8c..97332476c0225 100644 --- a/pkg/querier/queryrange/roundtrip.go +++ b/pkg/querier/queryrange/roundtrip.go @@ -15,6 +15,7 @@ import ( "github.com/grafana/loki/pkg/loghttp" "github.com/grafana/loki/pkg/logql/syntax" + "github.com/grafana/loki/pkg/logqlmodel/stats" "github.com/grafana/loki/pkg/querier/queryrange/queryrangebase" "github.com/grafana/loki/pkg/storage/chunk/cache" "github.com/grafana/loki/pkg/storage/config" @@ -52,7 +53,7 @@ func NewTripperware( err error ) if cfg.CacheResults { - c, err = cache.New(cfg.CacheConfig, registerer, log) + c, err = cache.New(cfg.CacheConfig, registerer, log, stats.ResultCache) if err != nil { return nil, nil, err } diff --git a/pkg/storage/chunk/cache/cache.go b/pkg/storage/chunk/cache/cache.go index 9e2d5e8f9e6af..6003db4ed1659 100644 --- a/pkg/storage/chunk/cache/cache.go +++ b/pkg/storage/chunk/cache/cache.go @@ -9,6 +9,8 @@ import ( "github.com/go-kit/log" "github.com/prometheus/client_golang/prometheus" + + "github.com/grafana/loki/pkg/logqlmodel/stats" ) // Cache byte arrays by key. @@ -22,6 +24,7 @@ type Cache interface { Store(ctx context.Context, key []string, buf [][]byte) error Fetch(ctx context.Context, keys []string) (found []string, bufs [][]byte, missing []string, err error) Stop() + GetCacheType() stats.CacheType } // Config for building Caches. @@ -83,7 +86,7 @@ func IsRedisSet(cfg Config) bool { } // New creates a new Cache using Config. -func New(cfg Config, reg prometheus.Registerer, logger log.Logger) (Cache, error) { +func New(cfg Config, reg prometheus.Registerer, logger log.Logger, cacheType stats.CacheType) (Cache, error) { if cfg.Cache != nil { return cfg.Cache, nil } @@ -95,7 +98,7 @@ func New(cfg Config, reg prometheus.Registerer, logger log.Logger) (Cache, error cfg.Fifocache.TTL = cfg.DefaultValidity } - if cache := NewFifoCache(cfg.Prefix+"fifocache", cfg.Fifocache, reg, logger); cache != nil { + if cache := NewFifoCache(cfg.Prefix+"fifocache", cfg.Fifocache, reg, logger, cacheType); cache != nil { caches = append(caches, Instrument(cfg.Prefix+"fifocache", cache, reg)) } } @@ -110,7 +113,7 @@ func New(cfg Config, reg prometheus.Registerer, logger log.Logger) (Cache, error } client := NewMemcachedClient(cfg.MemcacheClient, cfg.Prefix, reg, logger) - cache := NewMemcached(cfg.Memcache, client, cfg.Prefix, reg, logger) + cache := NewMemcached(cfg.Memcache, client, cfg.Prefix, reg, logger, cacheType) cacheName := cfg.Prefix + "memcache" caches = append(caches, NewBackground(cacheName, cfg.Background, Instrument(cacheName, cache, reg), reg)) @@ -125,7 +128,7 @@ func New(cfg Config, reg prometheus.Registerer, logger log.Logger) (Cache, error if err != nil { return nil, fmt.Errorf("redis client setup failed: %w", err) } - cache := NewRedisCache(cacheName, client, logger) + cache := NewRedisCache(cacheName, client, logger, cacheType) caches = append(caches, NewBackground(cacheName, cfg.Background, Instrument(cacheName, cache, reg), reg)) } diff --git a/pkg/storage/chunk/cache/cache_gen.go b/pkg/storage/chunk/cache/cache_gen.go index 022cb5194b1c4..5bd7038aa4016 100644 --- a/pkg/storage/chunk/cache/cache_gen.go +++ b/pkg/storage/chunk/cache/cache_gen.go @@ -2,6 +2,8 @@ package cache import ( "context" + + "github.com/grafana/loki/pkg/logqlmodel/stats" ) type contextKey int @@ -44,6 +46,10 @@ func (c GenNumMiddleware) Stop() { c.downstreamCache.Stop() } +func (c GenNumMiddleware) GetCacheType() stats.CacheType { + return c.downstreamCache.GetCacheType() +} + // InjectCacheGenNumber returns a derived context containing the cache gen. func InjectCacheGenNumber(ctx context.Context, cacheGen string) context.Context { return context.WithValue(ctx, interface{}(cacheGenContextKey), cacheGen) diff --git a/pkg/storage/chunk/cache/fifo_cache.go b/pkg/storage/chunk/cache/fifo_cache.go index 2392bc837153b..20cf11120fa42 100644 --- a/pkg/storage/chunk/cache/fifo_cache.go +++ b/pkg/storage/chunk/cache/fifo_cache.go @@ -17,6 +17,7 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" + "github.com/grafana/loki/pkg/logqlmodel/stats" util_log "github.com/grafana/loki/pkg/util/log" ) @@ -71,6 +72,8 @@ func parsebytes(s string) (uint64, error) { // FifoCache is a simple string -> interface{} cache which uses a fifo slide to // manage evictions. O(1) inserts and updates, O(1) gets. type FifoCache struct { + cacheType stats.CacheType + lock sync.RWMutex maxSizeItems int maxSizeBytes uint64 @@ -98,7 +101,7 @@ type cacheEntry struct { } // NewFifoCache returns a new initialised FifoCache of size. -func NewFifoCache(name string, cfg FifoCacheConfig, reg prometheus.Registerer, logger log.Logger) *FifoCache { +func NewFifoCache(name string, cfg FifoCacheConfig, reg prometheus.Registerer, logger log.Logger, cacheType stats.CacheType) *FifoCache { util_log.WarnExperimentalUse(fmt.Sprintf("In-memory (FIFO) cache - %s", name), logger) if cfg.DeprecatedSize > 0 { @@ -127,6 +130,8 @@ func NewFifoCache(name string, cfg FifoCacheConfig, reg prometheus.Registerer, l } cache := &FifoCache{ + cacheType: cacheType, + maxSizeItems: cfg.MaxSizeItems, maxSizeBytes: maxSizeBytes, entries: make(map[string]*list.Element), @@ -283,6 +288,10 @@ func (c *FifoCache) Stop() { c.memoryBytes.Set(float64(0)) } +func (c *FifoCache) GetCacheType() stats.CacheType { + return c.cacheType +} + func (c *FifoCache) put(key string, value []byte) { // See if we already have the item in the cache. element, ok := c.entries[key] diff --git a/pkg/storage/chunk/cache/instrumented.go b/pkg/storage/chunk/cache/instrumented.go index b9b32cbc7afd8..c1716a7cb21f9 100644 --- a/pkg/storage/chunk/cache/instrumented.go +++ b/pkg/storage/chunk/cache/instrumented.go @@ -9,6 +9,8 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" instr "github.com/weaveworks/common/instrument" + + "github.com/grafana/loki/pkg/logqlmodel/stats" ) // Instrument returns an instrumented cache. @@ -70,6 +72,8 @@ func (i *instrumentedCache) Store(ctx context.Context, keys []string, bufs [][]b i.storedValueSize.Observe(float64(len(bufs[j]))) } + stats.FromContext(ctx).AddCacheEntriesStored(i.Cache.GetCacheType(), len(keys)) + method := i.name + ".store" return instr.CollectedRequest(ctx, method, i.requestDuration, instr.ErrorCode, func(ctx context.Context) error { sp := ot.SpanFromContext(ctx) @@ -92,6 +96,9 @@ func (i *instrumentedCache) Fetch(ctx context.Context, keys []string) ([]string, method = i.name + ".fetch" ) + st := stats.FromContext(ctx) + st.AddCacheRequest(i.Cache.GetCacheType(), 1) + err := instr.CollectedRequest(ctx, method, i.requestDuration, instr.ErrorCode, func(ctx context.Context) error { sp := ot.SpanFromContext(ctx) sp.LogFields(otlog.Int("keys requested", len(keys))) @@ -106,8 +113,14 @@ func (i *instrumentedCache) Fetch(ctx context.Context, keys []string) ([]string, i.fetchedKeys.Add(float64(len(keys))) i.hits.Add(float64(len(found))) + + st.AddCacheEntriesFound(i.Cache.GetCacheType(), len(found)) + st.AddCacheEntriesRequested(i.Cache.GetCacheType(), len(keys)) + for j := range bufs { - i.fetchedValueSize.Observe(float64(len(bufs[j]))) + size := len(bufs[j]) + i.fetchedValueSize.Observe(float64(size)) + st.AddCacheBytesTransferred(i.Cache.GetCacheType(), size) } return found, bufs, missing, err diff --git a/pkg/storage/chunk/cache/memcached.go b/pkg/storage/chunk/cache/memcached.go index 8da4be22fa856..57b5ba83e0e1a 100644 --- a/pkg/storage/chunk/cache/memcached.go +++ b/pkg/storage/chunk/cache/memcached.go @@ -15,6 +15,7 @@ import ( "github.com/prometheus/client_golang/prometheus/promauto" instr "github.com/weaveworks/common/instrument" + "github.com/grafana/loki/pkg/logqlmodel/stats" util_log "github.com/grafana/loki/pkg/util/log" "github.com/grafana/loki/pkg/util/math" ) @@ -36,9 +37,10 @@ func (cfg *MemcachedConfig) RegisterFlagsWithPrefix(prefix, description string, // Memcached type caches chunks in memcached type Memcached struct { - cfg MemcachedConfig - memcache MemcachedClient - name string + cfg MemcachedConfig + memcache MemcachedClient + name string + cacheType stats.CacheType requestDuration *instr.HistogramCollector @@ -49,12 +51,13 @@ type Memcached struct { } // NewMemcached makes a new Memcached. -func NewMemcached(cfg MemcachedConfig, client MemcachedClient, name string, reg prometheus.Registerer, logger log.Logger) *Memcached { +func NewMemcached(cfg MemcachedConfig, client MemcachedClient, name string, reg prometheus.Registerer, logger log.Logger, cacheType stats.CacheType) *Memcached { c := &Memcached{ - cfg: cfg, - memcache: client, - name: name, - logger: logger, + cfg: cfg, + memcache: client, + name: name, + logger: logger, + cacheType: cacheType, requestDuration: instr.NewHistogramCollector( promauto.With(reg).NewHistogramVec(prometheus.HistogramOpts{ Namespace: "loki", @@ -234,6 +237,10 @@ func (c *Memcached) Stop() { c.wg.Wait() } +func (c *Memcached) GetCacheType() stats.CacheType { + return c.cacheType +} + // HashKey hashes key into something you can store in memcached. func HashKey(key string) string { hasher := fnv.New64a() diff --git a/pkg/storage/chunk/cache/mock.go b/pkg/storage/chunk/cache/mock.go index 7cc0cad7a0606..8064e793eb47d 100644 --- a/pkg/storage/chunk/cache/mock.go +++ b/pkg/storage/chunk/cache/mock.go @@ -3,6 +3,8 @@ package cache import ( "context" "sync" + + "github.com/grafana/loki/pkg/logqlmodel/stats" ) type mockCache struct { @@ -37,6 +39,10 @@ func (m *mockCache) Fetch(ctx context.Context, keys []string) (found []string, b func (m *mockCache) Stop() { } +func (m *mockCache) GetCacheType() stats.CacheType { + return "mock" +} + // NewMockCache makes a new MockCache. func NewMockCache() Cache { return &mockCache{ diff --git a/pkg/storage/chunk/cache/redis_cache.go b/pkg/storage/chunk/cache/redis_cache.go index ec3491db7e7d6..5a4f9f73b87a7 100644 --- a/pkg/storage/chunk/cache/redis_cache.go +++ b/pkg/storage/chunk/cache/redis_cache.go @@ -7,23 +7,26 @@ import ( "github.com/go-kit/log" "github.com/go-kit/log/level" + "github.com/grafana/loki/pkg/logqlmodel/stats" util_log "github.com/grafana/loki/pkg/util/log" ) // RedisCache type caches chunks in redis type RedisCache struct { - name string - redis *RedisClient - logger log.Logger + name string + cacheType stats.CacheType + redis *RedisClient + logger log.Logger } // NewRedisCache creates a new RedisCache -func NewRedisCache(name string, redisClient *RedisClient, logger log.Logger) *RedisCache { +func NewRedisCache(name string, redisClient *RedisClient, logger log.Logger, cacheType stats.CacheType) *RedisCache { util_log.WarnExperimentalUse(fmt.Sprintf("Redis cache - %s", name), logger) cache := &RedisCache{ - name: name, - redis: redisClient, - logger: logger, + name: name, + redis: redisClient, + logger: logger, + cacheType: cacheType, } if err := cache.redis.Ping(context.Background()); err != nil { level.Error(logger).Log("msg", "error connecting to redis", "name", name, "err", err) @@ -64,3 +67,7 @@ func (c *RedisCache) Store(ctx context.Context, keys []string, bufs [][]byte) er func (c *RedisCache) Stop() { _ = c.redis.Close() } + +func (c *RedisCache) GetCacheType() stats.CacheType { + return c.cacheType +} diff --git a/pkg/storage/chunk/cache/snappy.go b/pkg/storage/chunk/cache/snappy.go index 9fa708888d367..000827d1bcff5 100644 --- a/pkg/storage/chunk/cache/snappy.go +++ b/pkg/storage/chunk/cache/snappy.go @@ -6,6 +6,8 @@ import ( "github.com/go-kit/log" "github.com/go-kit/log/level" "github.com/golang/snappy" + + "github.com/grafana/loki/pkg/logqlmodel/stats" ) type snappyCache struct { @@ -47,3 +49,7 @@ func (s *snappyCache) Fetch(ctx context.Context, keys []string) ([]string, [][]b func (s *snappyCache) Stop() { s.next.Stop() } + +func (c *snappyCache) GetCacheType() stats.CacheType { + return c.next.GetCacheType() +} diff --git a/pkg/storage/chunk/cache/tiered.go b/pkg/storage/chunk/cache/tiered.go index ea8b7192108b0..3522b41f45b19 100644 --- a/pkg/storage/chunk/cache/tiered.go +++ b/pkg/storage/chunk/cache/tiered.go @@ -1,6 +1,10 @@ package cache -import "context" +import ( + "context" + + "github.com/grafana/loki/pkg/logqlmodel/stats" +) type tiered []Cache @@ -78,3 +82,7 @@ func (t tiered) Stop() { c.Stop() } } + +func (c tiered) GetCacheType() stats.CacheType { + return "tiered" +} diff --git a/pkg/storage/store.go b/pkg/storage/store.go index a1801cd415cb5..7a22ec9655973 100644 --- a/pkg/storage/store.go +++ b/pkg/storage/store.go @@ -87,19 +87,19 @@ func NewStore(cfg Config, storeCfg config.ChunkStoreConfig, schemaCfg config.Sch } } - indexReadCache, err := cache.New(cfg.IndexQueriesCacheConfig, registerer, logger) + indexReadCache, err := cache.New(cfg.IndexQueriesCacheConfig, registerer, logger, stats.IndexCache) if err != nil { return nil, err } - writeDedupeCache, err := cache.New(storeCfg.WriteDedupeCacheConfig, registerer, logger) + writeDedupeCache, err := cache.New(storeCfg.WriteDedupeCacheConfig, registerer, logger, stats.WriteDedupeCache) if err != nil { return nil, err } chunkCacheCfg := storeCfg.ChunkCacheConfig chunkCacheCfg.Prefix = "chunks" - chunksCache, err := cache.New(chunkCacheCfg, registerer, logger) + chunksCache, err := cache.New(chunkCacheCfg, registerer, logger, stats.ChunkCache) if err != nil { return nil, err } From 438581ee498e534fa62042c5187ab0448433cdec Mon Sep 17 00:00:00 2001 From: Danny Kopping Date: Fri, 3 Jun 2022 09:40:30 +0200 Subject: [PATCH 02/11] Adding metrics to metrics.go Signed-off-by: Danny Kopping --- pkg/logql/metrics.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pkg/logql/metrics.go b/pkg/logql/metrics.go index d918c65d0f5eb..c383f48ba7d4e 100644 --- a/pkg/logql/metrics.go +++ b/pkg/logql/metrics.go @@ -126,6 +126,13 @@ func RecordRangeAndInstantQueryMetrics( "total_entries", stats.Summary.TotalEntriesReturned, "queue_time", logql_stats.ConvertSecondsToNanoseconds(stats.Summary.QueueTime), "subqueries", stats.Summary.Subqueries, + "cached_chunks_req", stats.Caches.Chunk.EntriesRequested, + "cached_chunks_hit", stats.Caches.Chunk.EntriesFound, + "cached_chunks_bytes", stats.Caches.Chunk.BytesTransferred, + "cached_indexes_req", stats.Caches.Index.EntriesRequested, + "cached_indexes_hit", stats.Caches.Index.EntriesFound, + "cached_results_req", stats.Caches.Result.EntriesRequested, + "cached_results_hit", stats.Caches.Result.EntriesFound, }...) logValues = append(logValues, tagsToKeyValues(queryTags)...) From baa239c75bd0776c8180f883fb4794e75774b430 Mon Sep 17 00:00:00 2001 From: Danny Kopping Date: Mon, 6 Jun 2022 14:28:03 +0200 Subject: [PATCH 03/11] Creating new stats context for use in metric queries middleware Signed-off-by: Danny Kopping --- pkg/querier/queryrange/stats.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pkg/querier/queryrange/stats.go b/pkg/querier/queryrange/stats.go index cc0c2b6b6e491..230650e298d5d 100644 --- a/pkg/querier/queryrange/stats.go +++ b/pkg/querier/queryrange/stats.go @@ -110,8 +110,11 @@ func StatsCollectorMiddleware() queryrangebase.Middleware { logger := spanlogger.FromContext(ctx) start := time.Now() + // start a new statistics context to be used by middleware, which we will merge with the response's statistics + st, statsCtx := stats.NewContext(ctx) + // execute the request - resp, err := next.Do(ctx, req) + resp, err := next.Do(statsCtx, req) // collect stats and status var statistics *stats.Result @@ -145,6 +148,9 @@ func StatsCollectorMiddleware() queryrangebase.Middleware { } if statistics != nil { + // merge the response's statistics with the stats collected by the middleware + statistics.Merge(st.Result(time.Since(start), 0, totalEntries)) + // Re-calculate the summary: the queueTime result is already merged so should not be updated // Log and record metrics for the current query statistics.ComputeSummary(time.Since(start), 0, totalEntries) From f56d6428bb547f512a0c0177872470b4309a04d7 Mon Sep 17 00:00:00 2001 From: Danny Kopping Date: Mon, 6 Jun 2022 14:28:13 +0200 Subject: [PATCH 04/11] Clean up unnecessary log fields Signed-off-by: Danny Kopping --- pkg/logqlmodel/stats/context.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/pkg/logqlmodel/stats/context.go b/pkg/logqlmodel/stats/context.go index 5315e378e64a8..b0f19514c7057 100644 --- a/pkg/logqlmodel/stats/context.go +++ b/pkg/logqlmodel/stats/context.go @@ -400,17 +400,14 @@ func (c Caches) Log(log log.Logger) { "Cache.Chunk.Requests", c.Chunk.Requests, "Cache.Chunk.EntriesRequested", c.Chunk.EntriesRequested, "Cache.Chunk.EntriesFound", c.Chunk.EntriesFound, - "Cache.Chunk.EntriesStored", c.Chunk.EntriesStored, "Cache.Chunk.BytesTransferred", humanize.Bytes(uint64(c.Chunk.BytesTransferred)), "Cache.Index.Requests", c.Index.Requests, "Cache.Index.EntriesRequested", c.Index.EntriesRequested, "Cache.Index.EntriesFound", c.Index.EntriesFound, - "Cache.Index.EntriesStored", c.Index.EntriesStored, "Cache.Index.BytesTransferred", humanize.Bytes(uint64(c.Index.BytesTransferred)), "Cache.Result.Requests", c.Result.Requests, "Cache.Result.EntriesRequested", c.Result.EntriesRequested, "Cache.Result.EntriesFound", c.Result.EntriesFound, - "Cache.Result.EntriesStored", c.Result.EntriesStored, "Cache.Result.BytesTransferred", humanize.Bytes(uint64(c.Result.BytesTransferred)), ) } From 4e9fafba6d308f5342ce69ab48e01f3c2f5a9bb8 Mon Sep 17 00:00:00 2001 From: Danny Kopping Date: Mon, 6 Jun 2022 15:17:13 +0200 Subject: [PATCH 05/11] Fixing tests Signed-off-by: Danny Kopping --- pkg/querier/queryrange/codec_test.go | 29 ++++++++ pkg/querier/queryrange/prometheus_test.go | 23 +++++++ .../queryrangebase/results_cache_test.go | 11 +-- pkg/storage/chunk/cache/cache_test.go | 6 +- pkg/storage/chunk/cache/fifo_cache_test.go | 4 +- pkg/storage/chunk/cache/memcached_test.go | 8 +-- pkg/storage/chunk/cache/redis_cache_test.go | 2 +- .../chunk/tests/caching_fixtures_test.go | 3 +- .../series/index/caching_index_client_test.go | 12 ++-- .../stores/series/series_store_test.go | 3 +- pkg/storage/util_test.go | 3 +- pkg/util/marshal/legacy/marshal_test.go | 23 +++++++ pkg/util/marshal/marshal_test.go | 69 +++++++++++++++++++ 13 files changed, 172 insertions(+), 24 deletions(-) diff --git a/pkg/querier/queryrange/codec_test.go b/pkg/querier/queryrange/codec_test.go index 8520e92b56952..913494b7fe2b8 100644 --- a/pkg/querier/queryrange/codec_test.go +++ b/pkg/querier/queryrange/codec_test.go @@ -927,6 +927,29 @@ var ( "totalChunksDownloaded": 18 } }, + "cache": { + "chunk": { + "entriesFound": 0, + "entriesRequested": 0, + "entriesStored": 0, + "bytesTransferred": 0, + "requests": 0 + }, + "index": { + "entriesFound": 0, + "entriesRequested": 0, + "entriesStored": 0, + "bytesTransferred": 0, + "requests": 0 + }, + "result": { + "entriesFound": 0, + "entriesRequested": 0, + "entriesStored": 0, + "bytesTransferred": 0, + "requests": 0 + } + }, "summary": { "bytesProcessedPerSecond": 20, "execTime": 22, @@ -1121,6 +1144,12 @@ var ( TotalLinesSent: 9, TotalReached: 10, }, + + Caches: stats.Caches{ + Chunk: stats.Cache{}, + Index: stats.Cache{}, + Result: stats.Cache{}, + }, } ) diff --git a/pkg/querier/queryrange/prometheus_test.go b/pkg/querier/queryrange/prometheus_test.go index aff5172f634d8..3aefd4e1abd4a 100644 --- a/pkg/querier/queryrange/prometheus_test.go +++ b/pkg/querier/queryrange/prometheus_test.go @@ -47,6 +47,29 @@ var emptyStats = `"stats": { } } }, + "cache": { + "chunk": { + "entriesFound": 0, + "entriesRequested": 0, + "entriesStored": 0, + "bytesTransferred": 0, + "requests": 0 + }, + "index": { + "entriesFound": 0, + "entriesRequested": 0, + "entriesStored": 0, + "bytesTransferred": 0, + "requests": 0 + }, + "result": { + "entriesFound": 0, + "entriesRequested": 0, + "entriesStored": 0, + "bytesTransferred": 0, + "requests": 0 + } + }, "summary": { "bytesProcessedPerSecond": 0, "execTime": 0, diff --git a/pkg/querier/queryrange/queryrangebase/results_cache_test.go b/pkg/querier/queryrange/queryrangebase/results_cache_test.go index 1bb0182366ad5..a4545664d719e 100644 --- a/pkg/querier/queryrange/queryrangebase/results_cache_test.go +++ b/pkg/querier/queryrange/queryrangebase/results_cache_test.go @@ -16,6 +16,7 @@ import ( "github.com/weaveworks/common/user" "github.com/grafana/loki/pkg/logproto" + "github.com/grafana/loki/pkg/logqlmodel/stats" "github.com/grafana/loki/pkg/storage/chunk/cache" ) @@ -752,7 +753,7 @@ func TestResultsCache(t *testing.T) { Cache: cache.NewMockCache(), }, } - c, err := cache.New(cfg.CacheConfig, nil, log.NewNopLogger()) + c, err := cache.New(cfg.CacheConfig, nil, log.NewNopLogger(), stats.ResultCache) require.NoError(t, err) rcm, err := NewResultsCacheMiddleware( log.NewNopLogger(), @@ -794,7 +795,7 @@ func TestResultsCacheRecent(t *testing.T) { var cfg ResultsCacheConfig flagext.DefaultValues(&cfg) cfg.CacheConfig.Cache = cache.NewMockCache() - c, err := cache.New(cfg.CacheConfig, nil, log.NewNopLogger()) + c, err := cache.New(cfg.CacheConfig, nil, log.NewNopLogger(), stats.ResultCache) require.NoError(t, err) rcm, err := NewResultsCacheMiddleware( log.NewNopLogger(), @@ -857,7 +858,7 @@ func TestResultsCacheMaxFreshness(t *testing.T) { var cfg ResultsCacheConfig flagext.DefaultValues(&cfg) cfg.CacheConfig.Cache = cache.NewMockCache() - c, err := cache.New(cfg.CacheConfig, nil, log.NewNopLogger()) + c, err := cache.New(cfg.CacheConfig, nil, log.NewNopLogger(), stats.ResultCache) require.NoError(t, err) fakeLimits := tc.fakeLimits rcm, err := NewResultsCacheMiddleware( @@ -897,7 +898,7 @@ func Test_resultsCache_MissingData(t *testing.T) { Cache: cache.NewMockCache(), }, } - c, err := cache.New(cfg.CacheConfig, nil, log.NewNopLogger()) + c, err := cache.New(cfg.CacheConfig, nil, log.NewNopLogger(), stats.ResultCache) require.NoError(t, err) rm, err := NewResultsCacheMiddleware( log.NewNopLogger(), @@ -1008,7 +1009,7 @@ func TestResultsCacheShouldCacheFunc(t *testing.T) { var cfg ResultsCacheConfig flagext.DefaultValues(&cfg) cfg.CacheConfig.Cache = cache.NewMockCache() - c, err := cache.New(cfg.CacheConfig, nil, log.NewNopLogger()) + c, err := cache.New(cfg.CacheConfig, nil, log.NewNopLogger(), stats.ResultCache) require.NoError(t, err) rcm, err := NewResultsCacheMiddleware( log.NewNopLogger(), diff --git a/pkg/storage/chunk/cache/cache_test.go b/pkg/storage/chunk/cache/cache_test.go index 50329b51c6603..6d75f45a8d7eb 100644 --- a/pkg/storage/chunk/cache/cache_test.go +++ b/pkg/storage/chunk/cache/cache_test.go @@ -188,7 +188,7 @@ func testCache(t *testing.T, cache cache.Cache) { func TestMemcache(t *testing.T) { t.Run("Unbatched", func(t *testing.T) { cache := cache.NewMemcached(cache.MemcachedConfig{}, newMockMemcache(), - "test", nil, log.NewNopLogger()) + "test", nil, log.NewNopLogger(), "test") testCache(t, cache) }) @@ -196,14 +196,14 @@ func TestMemcache(t *testing.T) { cache := cache.NewMemcached(cache.MemcachedConfig{ BatchSize: 10, Parallelism: 3, - }, newMockMemcache(), "test", nil, log.NewNopLogger()) + }, newMockMemcache(), "test", nil, log.NewNopLogger(), "test") testCache(t, cache) }) } func TestFifoCache(t *testing.T) { cache := cache.NewFifoCache("test", cache.FifoCacheConfig{MaxSizeItems: 1e3, TTL: 1 * time.Hour}, - nil, log.NewNopLogger()) + nil, log.NewNopLogger(), "test") testCache(t, cache) } diff --git a/pkg/storage/chunk/cache/fifo_cache_test.go b/pkg/storage/chunk/cache/fifo_cache_test.go index f6714a88cf420..4c391c56792b9 100644 --- a/pkg/storage/chunk/cache/fifo_cache_test.go +++ b/pkg/storage/chunk/cache/fifo_cache_test.go @@ -38,7 +38,7 @@ func TestFifoCacheEviction(t *testing.T) { } for _, test := range tests { - c := NewFifoCache(test.name, test.cfg, nil, log.NewNopLogger()) + c := NewFifoCache(test.name, test.cfg, nil, log.NewNopLogger(), "test") ctx := context.Background() // Check put / get works @@ -193,7 +193,7 @@ func TestFifoCacheExpiry(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - c := NewFifoCache(test.name, test.cfg, nil, log.NewNopLogger()) + c := NewFifoCache(test.name, test.cfg, nil, log.NewNopLogger(), "test") ctx := context.Background() err := c.Store(ctx, []string{key1, key2, key3, key4}, [][]byte{data1, data2, data3, data4}) diff --git a/pkg/storage/chunk/cache/memcached_test.go b/pkg/storage/chunk/cache/memcached_test.go index d16a906619111..210be024c1b30 100644 --- a/pkg/storage/chunk/cache/memcached_test.go +++ b/pkg/storage/chunk/cache/memcached_test.go @@ -18,7 +18,7 @@ func TestMemcached(t *testing.T) { t.Run("unbatched", func(t *testing.T) { client := newMockMemcache() memcache := cache.NewMemcached(cache.MemcachedConfig{}, client, - "test", nil, log.NewNopLogger()) + "test", nil, log.NewNopLogger(), "test") testMemcache(t, memcache) }) @@ -28,7 +28,7 @@ func TestMemcached(t *testing.T) { memcache := cache.NewMemcached(cache.MemcachedConfig{ BatchSize: 10, Parallelism: 5, - }, client, "test", nil, log.NewNopLogger()) + }, client, "test", nil, log.NewNopLogger(), "test") testMemcache(t, memcache) }) @@ -95,7 +95,7 @@ func TestMemcacheFailure(t *testing.T) { t.Run("unbatched", func(t *testing.T) { client := newMockMemcacheFailing() memcache := cache.NewMemcached(cache.MemcachedConfig{}, client, - "test", nil, log.NewNopLogger()) + "test", nil, log.NewNopLogger(), "test") testMemcacheFailing(t, memcache) }) @@ -105,7 +105,7 @@ func TestMemcacheFailure(t *testing.T) { memcache := cache.NewMemcached(cache.MemcachedConfig{ BatchSize: 10, Parallelism: 5, - }, client, "test", nil, log.NewNopLogger()) + }, client, "test", nil, log.NewNopLogger(), "test") testMemcacheFailing(t, memcache) }) diff --git a/pkg/storage/chunk/cache/redis_cache_test.go b/pkg/storage/chunk/cache/redis_cache_test.go index 3048473dba911..0215b5702e74a 100644 --- a/pkg/storage/chunk/cache/redis_cache_test.go +++ b/pkg/storage/chunk/cache/redis_cache_test.go @@ -64,5 +64,5 @@ func mockRedisCache() (*RedisCache, error) { Addrs: []string{redisServer.Addr()}, }), } - return NewRedisCache("mock", redisClient, log.NewNopLogger()), nil + return NewRedisCache("mock", redisClient, log.NewNopLogger(), "test"), nil } diff --git a/pkg/storage/chunk/tests/caching_fixtures_test.go b/pkg/storage/chunk/tests/caching_fixtures_test.go index 3d8c45a946a45..44404afe50c02 100644 --- a/pkg/storage/chunk/tests/caching_fixtures_test.go +++ b/pkg/storage/chunk/tests/caching_fixtures_test.go @@ -8,6 +8,7 @@ import ( "github.com/grafana/dskit/flagext" "github.com/prometheus/client_golang/prometheus" + "github.com/grafana/loki/pkg/logqlmodel/stats" "github.com/grafana/loki/pkg/storage/chunk/cache" "github.com/grafana/loki/pkg/storage/chunk/client" "github.com/grafana/loki/pkg/storage/chunk/client/gcp" @@ -33,7 +34,7 @@ func (f fixture) Clients() (index.Client, client.Client, index.TableClient, conf indexClient = index.NewCachingIndexClient(indexClient, cache.NewFifoCache("index-fifo", cache.FifoCacheConfig{ MaxSizeItems: 500, TTL: 5 * time.Minute, - }, reg, logger), 5*time.Minute, limits, logger, false) + }, reg, logger, stats.ChunkCache), 5*time.Minute, limits, logger, false) return indexClient, chunkClient, tableClient, schemaConfig, closer, err } diff --git a/pkg/storage/stores/series/index/caching_index_client_test.go b/pkg/storage/stores/series/index/caching_index_client_test.go index b1962ad41735d..7c934740a4f94 100644 --- a/pkg/storage/stores/series/index/caching_index_client_test.go +++ b/pkg/storage/stores/series/index/caching_index_client_test.go @@ -49,7 +49,7 @@ func TestCachingStorageClientBasic(t *testing.T) { limits, err := defaultLimits() require.NoError(t, err) logger := log.NewNopLogger() - cache := cache.NewFifoCache("test", cache.FifoCacheConfig{MaxSizeItems: 10, TTL: 10 * time.Second}, nil, logger) + cache := cache.NewFifoCache("test", cache.FifoCacheConfig{MaxSizeItems: 10, TTL: 10 * time.Second}, nil, logger, "test") client := index.NewCachingIndexClient(store, cache, 1*time.Second, limits, logger, false) queries := []index.Query{{ TableName: "table", @@ -81,7 +81,7 @@ func TestTempCachingStorageClient(t *testing.T) { limits, err := defaultLimits() require.NoError(t, err) logger := log.NewNopLogger() - cache := cache.NewFifoCache("test", cache.FifoCacheConfig{MaxSizeItems: 10, TTL: 10 * time.Second}, nil, logger) + cache := cache.NewFifoCache("test", cache.FifoCacheConfig{MaxSizeItems: 10, TTL: 10 * time.Second}, nil, logger, "test") client := index.NewCachingIndexClient(store, cache, 100*time.Millisecond, limits, logger, false) queries := []index.Query{ {TableName: "table", HashValue: "foo"}, @@ -140,7 +140,7 @@ func TestPermCachingStorageClient(t *testing.T) { limits, err := defaultLimits() require.NoError(t, err) logger := log.NewNopLogger() - cache := cache.NewFifoCache("test", cache.FifoCacheConfig{MaxSizeItems: 10, TTL: 10 * time.Second}, nil, logger) + cache := cache.NewFifoCache("test", cache.FifoCacheConfig{MaxSizeItems: 10, TTL: 10 * time.Second}, nil, logger, "test") client := index.NewCachingIndexClient(store, cache, 100*time.Millisecond, limits, logger, false) queries := []index.Query{ {TableName: "table", HashValue: "foo", Immutable: true}, @@ -196,7 +196,7 @@ func TestCachingStorageClientEmptyResponse(t *testing.T) { limits, err := defaultLimits() require.NoError(t, err) logger := log.NewNopLogger() - cache := cache.NewFifoCache("test", cache.FifoCacheConfig{MaxSizeItems: 10, TTL: 10 * time.Second}, nil, logger) + cache := cache.NewFifoCache("test", cache.FifoCacheConfig{MaxSizeItems: 10, TTL: 10 * time.Second}, nil, logger, "test") client := index.NewCachingIndexClient(store, cache, 1*time.Second, limits, logger, false) queries := []index.Query{{TableName: "table", HashValue: "foo"}} err = client.QueryPages(ctx, queries, func(query index.Query, batch index.ReadBatchResult) bool { @@ -235,7 +235,7 @@ func TestCachingStorageClientCollision(t *testing.T) { limits, err := defaultLimits() require.NoError(t, err) logger := log.NewNopLogger() - cache := cache.NewFifoCache("test", cache.FifoCacheConfig{MaxSizeItems: 10, TTL: 10 * time.Second}, nil, logger) + cache := cache.NewFifoCache("test", cache.FifoCacheConfig{MaxSizeItems: 10, TTL: 10 * time.Second}, nil, logger, "test") client := index.NewCachingIndexClient(store, cache, 1*time.Second, limits, logger, false) queries := []index.Query{ {TableName: "table", HashValue: "foo", RangeValuePrefix: []byte("bar")}, @@ -415,7 +415,7 @@ func TestCachingStorageClientStoreQueries(t *testing.T) { require.NoError(t, err) logger := log.NewNopLogger() cache := &mockCache{ - Cache: cache.NewFifoCache("test", cache.FifoCacheConfig{MaxSizeItems: 10, TTL: 10 * time.Second}, nil, logger), + Cache: cache.NewFifoCache("test", cache.FifoCacheConfig{MaxSizeItems: 10, TTL: 10 * time.Second}, nil, logger, "test"), } client := index.NewCachingIndexClient(store, cache, 1*time.Second, limits, logger, disableBroadQueries) var callbackQueries []index.Query diff --git a/pkg/storage/stores/series/series_store_test.go b/pkg/storage/stores/series/series_store_test.go index 9160ef34c4f27..3f4e9b1538c53 100644 --- a/pkg/storage/stores/series/series_store_test.go +++ b/pkg/storage/stores/series/series_store_test.go @@ -19,6 +19,7 @@ import ( "github.com/weaveworks/common/user" "github.com/grafana/loki/pkg/ingester/client" + "github.com/grafana/loki/pkg/logqlmodel/stats" "github.com/grafana/loki/pkg/storage" "github.com/grafana/loki/pkg/storage/chunk" "github.com/grafana/loki/pkg/storage/chunk/cache" @@ -54,7 +55,7 @@ var ( flagext.DefaultValues(&storeCfg) storeCfg.WriteDedupeCacheConfig.Cache = cache.NewFifoCache("test", cache.FifoCacheConfig{ MaxSizeItems: 500, - }, prometheus.NewRegistry(), log.NewNopLogger()) + }, prometheus.NewRegistry(), log.NewNopLogger(), stats.ChunkCache) return storeCfg }, }, diff --git a/pkg/storage/util_test.go b/pkg/storage/util_test.go index f23238f46fc1e..771552c9a2853 100644 --- a/pkg/storage/util_test.go +++ b/pkg/storage/util_test.go @@ -15,6 +15,7 @@ import ( "github.com/grafana/loki/pkg/ingester/client" "github.com/grafana/loki/pkg/logproto" "github.com/grafana/loki/pkg/logql/syntax" + "github.com/grafana/loki/pkg/logqlmodel/stats" "github.com/grafana/loki/pkg/querier/astmapper" "github.com/grafana/loki/pkg/storage/chunk" "github.com/grafana/loki/pkg/storage/chunk/cache" @@ -241,7 +242,7 @@ func (m *mockChunkStore) GetChunkRefs(ctx context.Context, userID string, from, refs = append(refs, r) } - cache, err := cache.New(cache.Config{Prefix: "chunks"}, nil, util_log.Logger) + cache, err := cache.New(cache.Config{Prefix: "chunks"}, nil, util_log.Logger, stats.ChunkCache) if err != nil { panic(err) } diff --git a/pkg/util/marshal/legacy/marshal_test.go b/pkg/util/marshal/legacy/marshal_test.go index e565c40aabeab..074bdf4bebdc2 100644 --- a/pkg/util/marshal/legacy/marshal_test.go +++ b/pkg/util/marshal/legacy/marshal_test.go @@ -78,6 +78,29 @@ var queryTests = []struct { } } }, + "cache": { + "chunk": { + "entriesFound": 0, + "entriesRequested": 0, + "entriesStored": 0, + "bytesTransferred": 0, + "requests": 0 + }, + "index": { + "entriesFound": 0, + "entriesRequested": 0, + "entriesStored": 0, + "bytesTransferred": 0, + "requests": 0 + }, + "result": { + "entriesFound": 0, + "entriesRequested": 0, + "entriesStored": 0, + "bytesTransferred": 0, + "requests": 0 + } + }, "summary": { "bytesProcessedPerSecond": 0, "execTime": 0, diff --git a/pkg/util/marshal/marshal_test.go b/pkg/util/marshal/marshal_test.go index d11db731b492f..3a95a77685c03 100644 --- a/pkg/util/marshal/marshal_test.go +++ b/pkg/util/marshal/marshal_test.go @@ -84,6 +84,29 @@ var queryTests = []struct { } } }, + "cache": { + "chunk": { + "entriesFound": 0, + "entriesRequested": 0, + "entriesStored": 0, + "bytesTransferred": 0, + "requests": 0 + }, + "index": { + "entriesFound": 0, + "entriesRequested": 0, + "entriesStored": 0, + "bytesTransferred": 0, + "requests": 0 + }, + "result": { + "entriesFound": 0, + "entriesRequested": 0, + "entriesStored": 0, + "bytesTransferred": 0, + "requests": 0 + } + }, "summary": { "bytesProcessedPerSecond": 0, "execTime": 0, @@ -194,6 +217,29 @@ var queryTests = []struct { } } }, + "cache": { + "chunk": { + "entriesFound": 0, + "entriesRequested": 0, + "entriesStored": 0, + "bytesTransferred": 0, + "requests": 0 + }, + "index": { + "entriesFound": 0, + "entriesRequested": 0, + "entriesStored": 0, + "bytesTransferred": 0, + "requests": 0 + }, + "result": { + "entriesFound": 0, + "entriesRequested": 0, + "entriesStored": 0, + "bytesTransferred": 0, + "requests": 0 + } + }, "summary": { "bytesProcessedPerSecond": 0, "execTime": 0, @@ -321,6 +367,29 @@ var queryTests = []struct { } } }, + "cache": { + "chunk": { + "entriesFound": 0, + "entriesRequested": 0, + "entriesStored": 0, + "bytesTransferred": 0, + "requests": 0 + }, + "index": { + "entriesFound": 0, + "entriesRequested": 0, + "entriesStored": 0, + "bytesTransferred": 0, + "requests": 0 + }, + "result": { + "entriesFound": 0, + "entriesRequested": 0, + "entriesStored": 0, + "bytesTransferred": 0, + "requests": 0 + } + }, "summary": { "bytesProcessedPerSecond": 0, "execTime": 0, From 648b33550af493c05faf69fb884e2147d95f94e6 Mon Sep 17 00:00:00 2001 From: Danny Kopping Date: Mon, 6 Jun 2022 15:17:31 +0200 Subject: [PATCH 06/11] Adding stats tests Signed-off-by: Danny Kopping --- pkg/logql/metrics_test.go | 2 +- pkg/logqlmodel/stats/context_test.go | 64 ++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/pkg/logql/metrics_test.go b/pkg/logql/metrics_test.go index 46db6463a20bc..fc1acfad8fa4f 100644 --- a/pkg/logql/metrics_test.go +++ b/pkg/logql/metrics_test.go @@ -84,7 +84,7 @@ func TestLogSlowQuery(t *testing.T) { }, logqlmodel.Streams{logproto.Stream{Entries: make([]logproto.Entry, 10)}}) require.Equal(t, fmt.Sprintf( - "level=info org_id=foo traceID=%s latency=slow query=\"{foo=\\\"bar\\\"} |= \\\"buzz\\\"\" query_type=filter range_type=range length=1h0m0s step=1m0s duration=25.25s status=200 limit=1000 returned_lines=10 throughput=100kB total_bytes=100kB total_entries=10 queue_time=2ns subqueries=0 source=logvolhist feature=beta\n", + "level=info org_id=foo traceID=%s latency=slow query=\"{foo=\\\"bar\\\"} |= \\\"buzz\\\"\" query_type=filter range_type=range length=1h0m0s step=1m0s duration=25.25s status=200 limit=1000 returned_lines=10 throughput=100kB total_bytes=100kB total_entries=10 queue_time=2ns subqueries=0 cached_chunks_req=0 cached_chunks_hit=0 cached_chunks_bytes=0 cached_indexes_req=0 cached_indexes_hit=0 cached_results_req=0 cached_results_hit=0 source=logvolhist feature=beta\n", sp.Context().(jaeger.SpanContext).SpanID().String(), ), buf.String()) diff --git a/pkg/logqlmodel/stats/context_test.go b/pkg/logqlmodel/stats/context_test.go index 0b97024c9b88f..1123912239a1a 100644 --- a/pkg/logqlmodel/stats/context_test.go +++ b/pkg/logqlmodel/stats/context_test.go @@ -22,6 +22,9 @@ func TestResult(t *testing.T) { stats.AddChunksRef(50) stats.AddChunksDownloaded(60) stats.AddChunksDownloadTime(time.Second) + stats.AddCacheRequest(ChunkCache, 3) + stats.AddCacheRequest(IndexCache, 4) + stats.AddCacheRequest(ResultCache, 1) fakeIngesterQuery(ctx) fakeIngesterQuery(ctx) @@ -60,6 +63,17 @@ func TestResult(t *testing.T) { }, }, }, + Caches: Caches{ + Chunk: Cache{ + Requests: 3, + }, + Index: Cache{ + Requests: 4, + }, + Result: Cache{ + Requests: 1, + }, + }, Summary: Summary{ ExecTime: 2 * time.Second.Seconds(), QueueTime: 2 * time.Nanosecond.Seconds(), @@ -182,6 +196,19 @@ func TestResult_Merge(t *testing.T) { }, }, }, + Caches: Caches{ + Chunk: Cache{ + Requests: 5, + BytesTransferred: 1024, + }, + Index: Cache{ + EntriesRequested: 22, + EntriesFound: 2, + }, + Result: Cache{ + EntriesStored: 3, + }, + }, Summary: Summary{ ExecTime: 2 * time.Second.Seconds(), QueueTime: 2 * time.Nanosecond.Seconds(), @@ -230,6 +257,19 @@ func TestResult_Merge(t *testing.T) { }, }, }, + Caches: Caches{ + Chunk: Cache{ + Requests: 2 * 5, + BytesTransferred: 2 * 1024, + }, + Index: Cache{ + EntriesRequested: 2 * 22, + EntriesFound: 2 * 2, + }, + Result: Cache{ + EntriesStored: 2 * 3, + }, + }, Summary: Summary{ ExecTime: 2 * 2 * time.Second.Seconds(), QueueTime: 2 * 2 * time.Nanosecond.Seconds(), @@ -273,3 +313,27 @@ func TestIngester(t *testing.T) { }, }, statsCtx.Ingester()) } + +func TestCaches(t *testing.T) { + statsCtx, _ := NewContext(context.Background()) + + statsCtx.AddCacheRequest(ChunkCache, 5) + statsCtx.AddCacheEntriesStored(ResultCache, 3) + statsCtx.AddCacheEntriesRequested(IndexCache, 22) + statsCtx.AddCacheBytesTransferred(ChunkCache, 1024) + statsCtx.AddCacheEntriesFound(IndexCache, 2) + + require.Equal(t, Caches{ + Chunk: Cache{ + Requests: 5, + BytesTransferred: 1024, + }, + Index: Cache{ + EntriesRequested: 22, + EntriesFound: 2, + }, + Result: Cache{ + EntriesStored: 3, + }, + }, statsCtx.Caches()) +} From 6cb56653cf3f4a8353880a93c620e51299f0f5ac Mon Sep 17 00:00:00 2001 From: Danny Kopping Date: Mon, 6 Jun 2022 15:27:45 +0200 Subject: [PATCH 07/11] CHANGELOG entry Signed-off-by: Danny Kopping --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f525b190c658..4a169e4801e96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## Main +* [6317](https://github.com/grafana/loki/pull/6317/files) **dannykoping**: General: add cache usage statistics * [6099](https://github.com/grafana/loki/pull/6099/files) **cstyan**: Drop lines with malformed JSON in Promtail JSON pipeline stage * [6136](https://github.com/grafana/loki/pull/6136) **periklis**: Add support for alertmanager header authorization * [6102](https://github.com/grafana/loki/pull/6102) **timchenko-a**: Add multi-tenancy support to lambda-promtail From 311e89bc612333e99281d392df0b468b001d18c7 Mon Sep 17 00:00:00 2001 From: Danny Kopping Date: Mon, 6 Jun 2022 15:55:37 +0200 Subject: [PATCH 08/11] Appeasing the linter Documenting function Signed-off-by: Danny Kopping --- pkg/logqlmodel/stats/context.go | 2 +- pkg/storage/chunk/cache/cache.go | 1 + pkg/storage/chunk/cache/tiered.go | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/logqlmodel/stats/context.go b/pkg/logqlmodel/stats/context.go index b0f19514c7057..938f60780d4ff 100644 --- a/pkg/logqlmodel/stats/context.go +++ b/pkg/logqlmodel/stats/context.go @@ -56,7 +56,7 @@ type Context struct { type CacheType string const ( - ChunkCache CacheType = "chunk" + ChunkCache CacheType = "chunk" //nolint:staticcheck IndexCache = "index" ResultCache = "result" WriteDedupeCache = "write-dedupe" diff --git a/pkg/storage/chunk/cache/cache.go b/pkg/storage/chunk/cache/cache.go index 6003db4ed1659..d2f255592c6ad 100644 --- a/pkg/storage/chunk/cache/cache.go +++ b/pkg/storage/chunk/cache/cache.go @@ -24,6 +24,7 @@ type Cache interface { Store(ctx context.Context, key []string, buf [][]byte) error Fetch(ctx context.Context, keys []string) (found []string, bufs [][]byte, missing []string, err error) Stop() + // GetCacheType returns a string indicating the cache "type" for the purpose of grouping cache usage statistics GetCacheType() stats.CacheType } diff --git a/pkg/storage/chunk/cache/tiered.go b/pkg/storage/chunk/cache/tiered.go index 3522b41f45b19..5ff128d34d34e 100644 --- a/pkg/storage/chunk/cache/tiered.go +++ b/pkg/storage/chunk/cache/tiered.go @@ -83,6 +83,6 @@ func (t tiered) Stop() { } } -func (c tiered) GetCacheType() stats.CacheType { +func (t tiered) GetCacheType() stats.CacheType { return "tiered" } From 9aa789ee040e4764eadfd88678df0d3900b30e79 Mon Sep 17 00:00:00 2001 From: Danny Kopping Date: Mon, 6 Jun 2022 16:46:40 +0200 Subject: [PATCH 09/11] Moving CHANGELOG entry to appropriate section Signed-off-by: Danny Kopping --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a169e4801e96..5ffd78422409b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,5 @@ ## Main -* [6317](https://github.com/grafana/loki/pull/6317/files) **dannykoping**: General: add cache usage statistics * [6099](https://github.com/grafana/loki/pull/6099/files) **cstyan**: Drop lines with malformed JSON in Promtail JSON pipeline stage * [6136](https://github.com/grafana/loki/pull/6136) **periklis**: Add support for alertmanager header authorization * [6102](https://github.com/grafana/loki/pull/6102) **timchenko-a**: Add multi-tenancy support to lambda-promtail @@ -75,6 +74,7 @@ #### Loki ##### Enhancements +* [6317](https://github.com/grafana/loki/pull/6317/files) **dannykoping**: General: add cache usage statistics ##### Fixes * [6152](https://github.com/grafana/loki/pull/6152) **slim-bean**: Fixes unbounded ingester memory growth when live tailing under specific circumstances. From 769145d812e8be849280e4861736075156e1ebf9 Mon Sep 17 00:00:00 2001 From: Danny Kopping Date: Tue, 7 Jun 2022 12:48:35 +0200 Subject: [PATCH 10/11] Implementing a stats collector cache wrapper to simplify stats collection If we keep the stats collection in pkg/storage/chunk/cache/instrumented.go, then any implementation that wraps it will cause the stats collected to be incomplete. For example: NewBackground(cacheName, cfg.Background, Instrument(cacheName, cache, reg), reg)) - the background cache requests are not collected Signed-off-by: Danny Kopping --- pkg/logql/metrics.go | 15 +- pkg/logqlmodel/stats/context.go | 38 ++++- pkg/logqlmodel/stats/context_test.go | 2 +- pkg/logqlmodel/stats/stats.pb.go | 189 ++++++++++++++---------- pkg/logqlmodel/stats/stats.proto | 5 +- pkg/storage/chunk/cache/cache.go | 6 +- pkg/storage/chunk/cache/instrumented.go | 15 +- pkg/storage/chunk/cache/stats.go | 53 +++++++ pkg/storage/chunk/fetcher/fetcher.go | 12 ++ pkg/storage/store.go | 2 +- 10 files changed, 229 insertions(+), 108 deletions(-) create mode 100644 pkg/storage/chunk/cache/stats.go diff --git a/pkg/logql/metrics.go b/pkg/logql/metrics.go index c383f48ba7d4e..a00ce77cd5d1a 100644 --- a/pkg/logql/metrics.go +++ b/pkg/logql/metrics.go @@ -126,13 +126,14 @@ func RecordRangeAndInstantQueryMetrics( "total_entries", stats.Summary.TotalEntriesReturned, "queue_time", logql_stats.ConvertSecondsToNanoseconds(stats.Summary.QueueTime), "subqueries", stats.Summary.Subqueries, - "cached_chunks_req", stats.Caches.Chunk.EntriesRequested, - "cached_chunks_hit", stats.Caches.Chunk.EntriesFound, - "cached_chunks_bytes", stats.Caches.Chunk.BytesTransferred, - "cached_indexes_req", stats.Caches.Index.EntriesRequested, - "cached_indexes_hit", stats.Caches.Index.EntriesFound, - "cached_results_req", stats.Caches.Result.EntriesRequested, - "cached_results_hit", stats.Caches.Result.EntriesFound, + "cache_chunk_req", stats.Caches.Chunk.EntriesRequested, + "cache_chunk_hit", stats.Caches.Chunk.EntriesFound, + "cache_chunk_bytes_stored", stats.Caches.Chunk.BytesSent, + "cache_chunk_bytes_fetched", stats.Caches.Chunk.BytesReceived, + "cache_index_req", stats.Caches.Index.EntriesRequested, + "cache_index_hit", stats.Caches.Index.EntriesFound, + "cache_result_req", stats.Caches.Result.EntriesRequested, + "cache_result_hit", stats.Caches.Result.EntriesFound, }...) logValues = append(logValues, tagsToKeyValues(queryTags)...) diff --git a/pkg/logqlmodel/stats/context.go b/pkg/logqlmodel/stats/context.go index 938f60780d4ff..4b1ab3148ad55 100644 --- a/pkg/logqlmodel/stats/context.go +++ b/pkg/logqlmodel/stats/context.go @@ -200,7 +200,8 @@ func (c *Cache) Merge(m Cache) { c.EntriesRequested += m.EntriesRequested c.EntriesStored += m.EntriesStored c.Requests += m.Requests - c.BytesTransferred += m.BytesTransferred + c.BytesSent += m.BytesSent + c.BytesReceived += m.BytesReceived } // Merge merges two results of statistics. @@ -293,6 +294,7 @@ func (c *Context) AddChunksRef(i int64) { atomic.AddInt64(&c.store.TotalChunksRef, i) } +// AddCacheEntriesFound counts the number of cache entries requested and found func (c *Context) AddCacheEntriesFound(t CacheType, i int) { stats := c.getCacheStatsByType(t) if stats == nil { @@ -302,6 +304,7 @@ func (c *Context) AddCacheEntriesFound(t CacheType, i int) { atomic.AddInt32(&stats.EntriesFound, int32(i)) } +// AddCacheEntriesRequested counts the number of keys requested from the cache func (c *Context) AddCacheEntriesRequested(t CacheType, i int) { stats := c.getCacheStatsByType(t) if stats == nil { @@ -311,6 +314,9 @@ func (c *Context) AddCacheEntriesRequested(t CacheType, i int) { atomic.AddInt32(&stats.EntriesRequested, int32(i)) } +// AddCacheEntriesStored counts the number of keys *attempted* to be stored in the cache +// It should be noted that if a background writeback (https://grafana.com/docs/loki/latest/configuration/#cache_config) +// is configured we cannot know if these store attempts succeeded or not as this happens asynchronously func (c *Context) AddCacheEntriesStored(t CacheType, i int) { stats := c.getCacheStatsByType(t) if stats == nil { @@ -320,15 +326,29 @@ func (c *Context) AddCacheEntriesStored(t CacheType, i int) { atomic.AddInt32(&stats.EntriesStored, int32(i)) } -func (c *Context) AddCacheBytesTransferred(t CacheType, i int) { +// AddCacheBytesRetrieved counts the amount of bytes retrieved from the cache +func (c *Context) AddCacheBytesRetrieved(t CacheType, i int) { stats := c.getCacheStatsByType(t) if stats == nil { return } - atomic.AddInt64(&stats.BytesTransferred, int64(i)) + atomic.AddInt64(&stats.BytesReceived, int64(i)) } +// AddCacheBytesSent counts the amount of bytes sent to the cache +// It should be noted that if a background writeback (https://grafana.com/docs/loki/latest/configuration/#cache_config) +// is configured we cannot know if these bytes actually got stored or not as this happens asynchronously +func (c *Context) AddCacheBytesSent(t CacheType, i int) { + stats := c.getCacheStatsByType(t) + if stats == nil { + return + } + + atomic.AddInt64(&stats.BytesSent, int64(i)) +} + +// AddCacheRequest counts the number of fetch/store requests to the cache func (c *Context) AddCacheRequest(t CacheType, i int) { stats := c.getCacheStatsByType(t) if stats == nil { @@ -400,14 +420,20 @@ func (c Caches) Log(log log.Logger) { "Cache.Chunk.Requests", c.Chunk.Requests, "Cache.Chunk.EntriesRequested", c.Chunk.EntriesRequested, "Cache.Chunk.EntriesFound", c.Chunk.EntriesFound, - "Cache.Chunk.BytesTransferred", humanize.Bytes(uint64(c.Chunk.BytesTransferred)), + "Cache.Chunk.EntriesStored", c.Chunk.EntriesStored, + "Cache.Chunk.BytesSent", humanize.Bytes(uint64(c.Chunk.BytesSent)), + "Cache.Chunk.BytesReceived", humanize.Bytes(uint64(c.Chunk.BytesReceived)), "Cache.Index.Requests", c.Index.Requests, "Cache.Index.EntriesRequested", c.Index.EntriesRequested, "Cache.Index.EntriesFound", c.Index.EntriesFound, - "Cache.Index.BytesTransferred", humanize.Bytes(uint64(c.Index.BytesTransferred)), + "Cache.Index.EntriesStored", c.Index.EntriesStored, + "Cache.Index.BytesSent", humanize.Bytes(uint64(c.Index.BytesSent)), + "Cache.Index.BytesReceived", humanize.Bytes(uint64(c.Index.BytesReceived)), "Cache.Result.Requests", c.Result.Requests, "Cache.Result.EntriesRequested", c.Result.EntriesRequested, "Cache.Result.EntriesFound", c.Result.EntriesFound, - "Cache.Result.BytesTransferred", humanize.Bytes(uint64(c.Result.BytesTransferred)), + "Cache.Result.EntriesStored", c.Result.EntriesStored, + "Cache.Result.BytesSent", humanize.Bytes(uint64(c.Result.BytesSent)), + "Cache.Result.BytesReceived", humanize.Bytes(uint64(c.Result.BytesReceived)), ) } diff --git a/pkg/logqlmodel/stats/context_test.go b/pkg/logqlmodel/stats/context_test.go index 1123912239a1a..02cec0e2bb217 100644 --- a/pkg/logqlmodel/stats/context_test.go +++ b/pkg/logqlmodel/stats/context_test.go @@ -320,7 +320,7 @@ func TestCaches(t *testing.T) { statsCtx.AddCacheRequest(ChunkCache, 5) statsCtx.AddCacheEntriesStored(ResultCache, 3) statsCtx.AddCacheEntriesRequested(IndexCache, 22) - statsCtx.AddCacheBytesTransferred(ChunkCache, 1024) + statsCtx.AddCacheBytesRetrieved(ChunkCache, 1024) statsCtx.AddCacheEntriesFound(IndexCache, 2) require.Equal(t, Caches{ diff --git a/pkg/logqlmodel/stats/stats.pb.go b/pkg/logqlmodel/stats/stats.pb.go index 75b9102070984..509645e9b195b 100644 --- a/pkg/logqlmodel/stats/stats.pb.go +++ b/pkg/logqlmodel/stats/stats.pb.go @@ -550,8 +550,9 @@ type Cache struct { EntriesFound int32 `protobuf:"varint,1,opt,name=entriesFound,proto3" json:"entriesFound"` EntriesRequested int32 `protobuf:"varint,2,opt,name=entriesRequested,proto3" json:"entriesRequested"` EntriesStored int32 `protobuf:"varint,3,opt,name=entriesStored,proto3" json:"entriesStored"` - BytesTransferred int64 `protobuf:"varint,4,opt,name=bytesTransferred,proto3" json:"bytesTransferred"` - Requests int32 `protobuf:"varint,5,opt,name=requests,proto3" json:"requests"` + BytesReceived int64 `protobuf:"varint,4,opt,name=bytesReceived,proto3" json:"bytesReceived"` + BytesSent int64 `protobuf:"varint,5,opt,name=bytesSent,proto3" json:"bytesSent"` + Requests int32 `protobuf:"varint,6,opt,name=requests,proto3" json:"requests"` } func (m *Cache) Reset() { *m = Cache{} } @@ -607,9 +608,16 @@ func (m *Cache) GetEntriesStored() int32 { return 0 } -func (m *Cache) GetBytesTransferred() int64 { +func (m *Cache) GetBytesReceived() int64 { if m != nil { - return m.BytesTransferred + return m.BytesReceived + } + return 0 +} + +func (m *Cache) GetBytesSent() int64 { + if m != nil { + return m.BytesSent } return 0 } @@ -635,65 +643,66 @@ func init() { func init() { proto.RegisterFile("pkg/logqlmodel/stats/stats.proto", fileDescriptor_6cdfe5d2aea33ebb) } var fileDescriptor_6cdfe5d2aea33ebb = []byte{ - // 924 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0x4f, 0x8f, 0xdb, 0x44, - 0x14, 0x8f, 0x93, 0x75, 0xb2, 0x1d, 0xf6, 0x5f, 0xa7, 0x2d, 0x0d, 0x20, 0xd9, 0xab, 0x9c, 0x56, - 0x02, 0x36, 0xe2, 0x8f, 0x84, 0x40, 0x54, 0x42, 0xde, 0x52, 0x69, 0xa5, 0x22, 0xca, 0xdb, 0x72, - 0xe1, 0xe6, 0x38, 0xb3, 0x59, 0x6b, 0x1d, 0xcf, 0x66, 0x6c, 0x8b, 0xf6, 0xc6, 0x8d, 0x23, 0x7c, - 0x06, 0xd4, 0x03, 0x17, 0xbe, 0x47, 0x8f, 0x7b, 0xec, 0xc9, 0x62, 0xb3, 0x17, 0xe4, 0x53, 0x25, - 0xbe, 0x00, 0x9a, 0x37, 0x13, 0xdb, 0xe3, 0x38, 0x12, 0x97, 0xcc, 0xbc, 0xdf, 0xef, 0xfd, 0xe6, - 0xcd, 0x9f, 0xf7, 0x5e, 0x4c, 0x0e, 0xaf, 0x2e, 0x67, 0xe3, 0x88, 0xcf, 0x16, 0xd1, 0x9c, 0x4f, - 0x59, 0x34, 0x4e, 0x52, 0x3f, 0x4d, 0xd4, 0xef, 0xf1, 0x95, 0xe0, 0x29, 0xa7, 0x36, 0x1a, 0xef, - 0x7f, 0x3c, 0x0b, 0xd3, 0x8b, 0x6c, 0x72, 0x1c, 0xf0, 0xf9, 0x78, 0xc6, 0x67, 0x7c, 0x8c, 0xec, - 0x24, 0x3b, 0x47, 0x0b, 0x0d, 0x9c, 0x29, 0xd5, 0xe8, 0x5f, 0x8b, 0xf4, 0x81, 0x25, 0x59, 0x94, - 0xd2, 0x2f, 0xc9, 0x20, 0xc9, 0xe6, 0x73, 0x5f, 0xbc, 0x1c, 0x5a, 0x87, 0xd6, 0xd1, 0x3b, 0x9f, - 0xee, 0x1d, 0xab, 0xf5, 0xcf, 0x14, 0xea, 0xed, 0xbf, 0xce, 0xdd, 0x4e, 0x91, 0xbb, 0x2b, 0x37, - 0x58, 0x4d, 0xa4, 0x74, 0x91, 0x31, 0x11, 0x32, 0x31, 0xec, 0x1a, 0xd2, 0x1f, 0x14, 0x5a, 0x49, - 0xb5, 0x1b, 0xac, 0x26, 0xf4, 0x11, 0xd9, 0x0e, 0xe3, 0x19, 0x4b, 0x52, 0x26, 0x86, 0x3d, 0xd4, - 0xee, 0x6b, 0xed, 0xa9, 0x86, 0xbd, 0x03, 0x2d, 0x2e, 0x1d, 0xa1, 0x9c, 0xd1, 0xcf, 0x49, 0x3f, - 0xf0, 0x83, 0x0b, 0x96, 0x0c, 0xb7, 0x50, 0xbc, 0xab, 0xc5, 0x27, 0x08, 0x7a, 0xbb, 0x5a, 0x6a, - 0xa3, 0x13, 0x68, 0xdf, 0xd1, 0x2b, 0x8b, 0xf4, 0x95, 0x07, 0xfd, 0x84, 0xd8, 0xc1, 0x45, 0x16, - 0x5f, 0xea, 0x33, 0xef, 0xd4, 0xf5, 0x35, 0xb9, 0x74, 0x01, 0x35, 0x48, 0x49, 0x18, 0x4f, 0xd9, - 0x0b, 0x7d, 0xd6, 0x0d, 0x12, 0x74, 0x01, 0x35, 0xc8, 0x6d, 0x0a, 0xbc, 0x65, 0x7d, 0x46, 0x53, - 0xb3, 0xa7, 0x35, 0xda, 0x07, 0xf4, 0x38, 0xfa, 0x63, 0x8b, 0x0c, 0xf4, 0xe5, 0xd3, 0x1f, 0xc9, - 0xc3, 0xc9, 0xcb, 0x94, 0x25, 0xcf, 0x04, 0x0f, 0x58, 0x92, 0xb0, 0xe9, 0x33, 0x26, 0xce, 0x58, - 0xc0, 0xe3, 0x29, 0xee, 0xbc, 0xe7, 0x7d, 0x50, 0xe4, 0xee, 0x26, 0x17, 0xd8, 0x44, 0xc8, 0x65, - 0xa3, 0x30, 0x6e, 0x5d, 0xb6, 0x5b, 0x2d, 0xbb, 0xc1, 0x05, 0x36, 0x11, 0xf4, 0x94, 0xdc, 0x4b, - 0x79, 0xea, 0x47, 0x9e, 0x11, 0x16, 0x0f, 0xdf, 0xf3, 0x1e, 0x16, 0xb9, 0xdb, 0x46, 0x43, 0x1b, - 0x58, 0x2e, 0xf5, 0xd4, 0x08, 0x85, 0xcf, 0x5d, 0x5f, 0xca, 0xa4, 0xa1, 0x0d, 0xa4, 0x47, 0x64, - 0x9b, 0xbd, 0x60, 0xc1, 0xf3, 0x70, 0xce, 0x86, 0xf6, 0xa1, 0x75, 0x64, 0x79, 0x3b, 0x32, 0xad, - 0x56, 0x18, 0x94, 0x33, 0xfa, 0x21, 0xb9, 0xb3, 0xc8, 0x58, 0xc6, 0xd0, 0xb5, 0x8f, 0xae, 0xbb, - 0x45, 0xee, 0x56, 0x20, 0x54, 0x53, 0x7a, 0x4c, 0x48, 0x92, 0x4d, 0x54, 0x42, 0x27, 0xc3, 0x01, - 0x6e, 0x6c, 0xaf, 0xc8, 0xdd, 0x1a, 0x0a, 0xb5, 0x39, 0x7d, 0x4a, 0xee, 0xe3, 0xee, 0xbe, 0x8d, - 0x53, 0xe4, 0x58, 0x9a, 0x89, 0x98, 0x4d, 0x87, 0xdb, 0xa8, 0x1c, 0x16, 0xb9, 0xdb, 0xca, 0x43, - 0x2b, 0x3a, 0xfa, 0x9a, 0x0c, 0x74, 0x95, 0xc9, 0xc4, 0x4c, 0x52, 0x2e, 0x58, 0x23, 0x97, 0xcf, - 0x24, 0x56, 0x25, 0x26, 0xba, 0x80, 0x1a, 0x46, 0x7f, 0x75, 0xc9, 0xf6, 0x69, 0x55, 0x4c, 0x3b, - 0x18, 0x02, 0x98, 0x4c, 0x4b, 0x95, 0x58, 0xb6, 0x77, 0x50, 0xe4, 0xae, 0x81, 0x83, 0x61, 0xd1, - 0x27, 0x84, 0xa2, 0x7d, 0x22, 0x8b, 0x23, 0xf9, 0xce, 0x4f, 0x51, 0xab, 0xb2, 0xe7, 0xdd, 0x22, - 0x77, 0x5b, 0x58, 0x68, 0xc1, 0xca, 0xe8, 0x1e, 0xda, 0x89, 0x4e, 0x96, 0x2a, 0xba, 0xc6, 0xc1, - 0xb0, 0xe8, 0x57, 0x64, 0xaf, 0x7a, 0xea, 0x33, 0x16, 0xa7, 0x3a, 0x33, 0x68, 0x91, 0xbb, 0x0d, - 0x06, 0x1a, 0x76, 0x75, 0x5f, 0xf6, 0xff, 0xbe, 0xaf, 0xdf, 0xba, 0xc4, 0x46, 0xbe, 0x0c, 0xac, - 0x0e, 0x01, 0xec, 0x5c, 0xd7, 0x61, 0x15, 0xb8, 0x64, 0xa0, 0x61, 0xd3, 0xef, 0xc9, 0x83, 0x1a, - 0xf2, 0x98, 0xff, 0x1c, 0x47, 0xdc, 0x9f, 0x96, 0xb7, 0xf6, 0x5e, 0x91, 0xbb, 0xed, 0x0e, 0xd0, - 0x0e, 0xcb, 0x37, 0x08, 0x0c, 0x0c, 0x13, 0xb7, 0x57, 0xbd, 0xc1, 0x3a, 0x0b, 0x2d, 0x58, 0xd5, - 0x0d, 0xb7, 0xcc, 0x36, 0x25, 0xb1, 0xf6, 0x6e, 0x38, 0xfa, 0xb5, 0x47, 0x6c, 0xe4, 0xe5, 0x8d, - 0x5c, 0x30, 0x7f, 0xaa, 0x9c, 0x65, 0x11, 0xd7, 0x9f, 0xc2, 0x64, 0xa0, 0x61, 0x1b, 0x5a, 0x7c, - 0x20, 0x7c, 0x93, 0xa6, 0x16, 0x19, 0x68, 0xd8, 0xf4, 0x84, 0xdc, 0x9d, 0xb2, 0x80, 0xcf, 0xaf, - 0x04, 0x96, 0xb9, 0x0a, 0xdd, 0x47, 0xf9, 0x83, 0x22, 0x77, 0xd7, 0x49, 0x58, 0x87, 0x9a, 0x8b, - 0xa8, 0x3d, 0x0c, 0xda, 0x17, 0x51, 0xdb, 0x58, 0x87, 0xe8, 0x23, 0xb2, 0xdf, 0xdc, 0x87, 0x2a, - 0xea, 0x7b, 0x45, 0xee, 0x36, 0x29, 0x68, 0x02, 0x52, 0x8e, 0xcf, 0xfb, 0x38, 0xbb, 0x8a, 0xc2, - 0xc0, 0x97, 0xf2, 0x3b, 0x95, 0xbc, 0x41, 0x41, 0x13, 0x18, 0xbd, 0xea, 0x12, 0x1b, 0xff, 0x50, - 0x64, 0x29, 0x31, 0xd5, 0x26, 0x9e, 0xf0, 0x2c, 0x36, 0x0a, 0xb9, 0x8e, 0x83, 0x61, 0xd1, 0x6f, - 0xc8, 0x01, 0x5b, 0x35, 0x97, 0x45, 0x26, 0x5b, 0x82, 0x4a, 0x48, 0xdb, 0xbb, 0x5f, 0xe4, 0xee, - 0x1a, 0x07, 0x6b, 0x08, 0xfd, 0x82, 0xec, 0x6a, 0x0c, 0x6b, 0x44, 0x35, 0x7c, 0xdb, 0xbb, 0x5b, - 0xe4, 0xae, 0x49, 0x80, 0x69, 0xca, 0xd0, 0xf8, 0x0f, 0xf5, 0x5c, 0xf8, 0x71, 0x72, 0xce, 0x84, - 0x28, 0x3b, 0x3c, 0x86, 0x6e, 0x72, 0xb0, 0x86, 0xc8, 0xde, 0x2e, 0xd4, 0x3e, 0x54, 0xea, 0xd8, - 0xaa, 0xb7, 0xaf, 0x30, 0x28, 0x67, 0xde, 0xe4, 0xfa, 0xc6, 0xe9, 0xbc, 0xb9, 0x71, 0x3a, 0x6f, - 0x6f, 0x1c, 0xeb, 0x97, 0xa5, 0x63, 0xfd, 0xb9, 0x74, 0xac, 0xd7, 0x4b, 0xc7, 0xba, 0x5e, 0x3a, - 0xd6, 0xdf, 0x4b, 0xc7, 0xfa, 0x67, 0xe9, 0x74, 0xde, 0x2e, 0x1d, 0xeb, 0xf7, 0x5b, 0xa7, 0x73, - 0x7d, 0xeb, 0x74, 0xde, 0xdc, 0x3a, 0x9d, 0x9f, 0x3e, 0xaa, 0x7f, 0x57, 0x09, 0xff, 0xdc, 0x8f, - 0xfd, 0x71, 0xc4, 0x2f, 0xc3, 0x71, 0xdb, 0x87, 0xd9, 0xa4, 0x8f, 0x5f, 0x57, 0x9f, 0xfd, 0x17, - 0x00, 0x00, 0xff, 0xff, 0xaf, 0xcd, 0x69, 0x7f, 0xb7, 0x09, 0x00, 0x00, + // 932 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0x4b, 0x6f, 0xe4, 0x44, + 0x10, 0x1e, 0xcf, 0xc4, 0x33, 0xd9, 0x26, 0xaf, 0xed, 0xdd, 0x65, 0x0d, 0x48, 0x76, 0x34, 0xa7, + 0x48, 0x40, 0x46, 0x3c, 0x24, 0x04, 0x62, 0x25, 0xe4, 0x2c, 0x2b, 0x45, 0x5a, 0xc4, 0x52, 0x81, + 0x0b, 0x37, 0x8f, 0xdd, 0x99, 0x58, 0xf1, 0xb8, 0x13, 0x3f, 0x60, 0xf7, 0xc6, 0x8d, 0x23, 0xfc, + 0x06, 0xc4, 0x81, 0x0b, 0xff, 0x23, 0xc7, 0x1c, 0xf7, 0x64, 0x91, 0xc9, 0x05, 0xf9, 0x14, 0x89, + 0x3f, 0x80, 0xba, 0xba, 0xc7, 0x76, 0x7b, 0x3c, 0xd2, 0x5e, 0xa6, 0xab, 0xbe, 0xaf, 0xbe, 0x7e, + 0x56, 0xd5, 0x98, 0xec, 0x5f, 0x9c, 0xcf, 0x26, 0x11, 0x9f, 0x5d, 0x46, 0x73, 0x1e, 0xb0, 0x68, + 0x92, 0x66, 0x5e, 0x96, 0xca, 0xdf, 0xc3, 0x8b, 0x84, 0x67, 0x9c, 0x9a, 0xe8, 0xbc, 0xfb, 0xe1, + 0x2c, 0xcc, 0xce, 0xf2, 0xe9, 0xa1, 0xcf, 0xe7, 0x93, 0x19, 0x9f, 0xf1, 0x09, 0xb2, 0xd3, 0xfc, + 0x14, 0x3d, 0x74, 0xd0, 0x92, 0xaa, 0xf1, 0x7f, 0x06, 0x19, 0x02, 0x4b, 0xf3, 0x28, 0xa3, 0x9f, + 0x93, 0x51, 0x9a, 0xcf, 0xe7, 0x5e, 0xf2, 0xca, 0x32, 0xf6, 0x8d, 0x83, 0xb7, 0x3e, 0xde, 0x39, + 0x94, 0xf3, 0x9f, 0x48, 0xd4, 0xdd, 0xbd, 0x2a, 0x9c, 0x5e, 0x59, 0x38, 0xcb, 0x30, 0x58, 0x1a, + 0x42, 0x7a, 0x99, 0xb3, 0x24, 0x64, 0x89, 0xd5, 0xd7, 0xa4, 0xdf, 0x49, 0xb4, 0x96, 0xaa, 0x30, + 0x58, 0x1a, 0xf4, 0x09, 0xd9, 0x0c, 0xe3, 0x19, 0x4b, 0x33, 0x96, 0x58, 0x03, 0xd4, 0xee, 0x2a, + 0xed, 0xb1, 0x82, 0xdd, 0x3d, 0x25, 0xae, 0x02, 0xa1, 0xb2, 0xe8, 0xa7, 0x64, 0xe8, 0x7b, 0xfe, + 0x19, 0x4b, 0xad, 0x0d, 0x14, 0x6f, 0x2b, 0xf1, 0x11, 0x82, 0xee, 0xb6, 0x92, 0x9a, 0x18, 0x04, + 0x2a, 0x76, 0xfc, 0xa7, 0x41, 0x86, 0x32, 0x82, 0x7e, 0x44, 0x4c, 0xff, 0x2c, 0x8f, 0xcf, 0xd5, + 0x99, 0xb7, 0x9a, 0xfa, 0x86, 0x5c, 0x84, 0x80, 0x1c, 0x84, 0x24, 0x8c, 0x03, 0xf6, 0x52, 0x9d, + 0x75, 0x8d, 0x04, 0x43, 0x40, 0x0e, 0x62, 0x9b, 0x09, 0xde, 0xb2, 0x3a, 0xa3, 0xae, 0xd9, 0x51, + 0x1a, 0x15, 0x03, 0x6a, 0x1c, 0xff, 0xb1, 0x41, 0x46, 0xea, 0xf2, 0xe9, 0x0f, 0xe4, 0xf1, 0xf4, + 0x55, 0xc6, 0xd2, 0x17, 0x09, 0xf7, 0x59, 0x9a, 0xb2, 0xe0, 0x05, 0x4b, 0x4e, 0x98, 0xcf, 0xe3, + 0x00, 0x77, 0x3e, 0x70, 0xdf, 0x2b, 0x0b, 0x67, 0x5d, 0x08, 0xac, 0x23, 0xc4, 0xb4, 0x51, 0x18, + 0x77, 0x4e, 0xdb, 0xaf, 0xa7, 0x5d, 0x13, 0x02, 0xeb, 0x08, 0x7a, 0x4c, 0x1e, 0x64, 0x3c, 0xf3, + 0x22, 0x57, 0x5b, 0x16, 0x0f, 0x3f, 0x70, 0x1f, 0x97, 0x85, 0xd3, 0x45, 0x43, 0x17, 0x58, 0x4d, + 0xf5, 0x5c, 0x5b, 0x0a, 0x9f, 0xbb, 0x39, 0x95, 0x4e, 0x43, 0x17, 0x48, 0x0f, 0xc8, 0x26, 0x7b, + 0xc9, 0xfc, 0xef, 0xc3, 0x39, 0xb3, 0xcc, 0x7d, 0xe3, 0xc0, 0x70, 0xb7, 0x44, 0x5a, 0x2d, 0x31, + 0xa8, 0x2c, 0xfa, 0x3e, 0xb9, 0x77, 0x99, 0xb3, 0x9c, 0x61, 0xe8, 0x10, 0x43, 0xb7, 0xcb, 0xc2, + 0xa9, 0x41, 0xa8, 0x4d, 0x7a, 0x48, 0x48, 0x9a, 0x4f, 0x65, 0x42, 0xa7, 0xd6, 0x08, 0x37, 0xb6, + 0x53, 0x16, 0x4e, 0x03, 0x85, 0x86, 0x4d, 0x9f, 0x93, 0x87, 0xb8, 0xbb, 0xaf, 0xe3, 0x0c, 0x39, + 0x96, 0xe5, 0x49, 0xcc, 0x02, 0x6b, 0x13, 0x95, 0x56, 0x59, 0x38, 0x9d, 0x3c, 0x74, 0xa2, 0xe3, + 0x2f, 0xc9, 0x48, 0x55, 0x99, 0x48, 0xcc, 0x34, 0xe3, 0x09, 0x6b, 0xe5, 0xf2, 0x89, 0xc0, 0xea, + 0xc4, 0xc4, 0x10, 0x90, 0xc3, 0xf8, 0xef, 0x3e, 0xd9, 0x3c, 0xae, 0x8b, 0x69, 0x0b, 0x97, 0x00, + 0x26, 0xd2, 0x52, 0x26, 0x96, 0xe9, 0xee, 0x95, 0x85, 0xa3, 0xe1, 0xa0, 0x79, 0xf4, 0x19, 0xa1, + 0xe8, 0x1f, 0x89, 0xe2, 0x48, 0xbf, 0xf1, 0x32, 0xd4, 0xca, 0xec, 0x79, 0xbb, 0x2c, 0x9c, 0x0e, + 0x16, 0x3a, 0xb0, 0x6a, 0x75, 0x17, 0xfd, 0x54, 0x25, 0x4b, 0xbd, 0xba, 0xc2, 0x41, 0xf3, 0xe8, + 0x17, 0x64, 0xa7, 0x7e, 0xea, 0x13, 0x16, 0x67, 0x2a, 0x33, 0x68, 0x59, 0x38, 0x2d, 0x06, 0x5a, + 0x7e, 0x7d, 0x5f, 0xe6, 0x1b, 0xdf, 0xd7, 0x6f, 0x7d, 0x62, 0x22, 0x5f, 0x2d, 0x2c, 0x0f, 0x01, + 0xec, 0x54, 0xd5, 0x61, 0xbd, 0x70, 0xc5, 0x40, 0xcb, 0xa7, 0xdf, 0x92, 0x47, 0x0d, 0xe4, 0x29, + 0xff, 0x39, 0x8e, 0xb8, 0x17, 0x54, 0xb7, 0xf6, 0x4e, 0x59, 0x38, 0xdd, 0x01, 0xd0, 0x0d, 0x8b, + 0x37, 0xf0, 0x35, 0x0c, 0x13, 0x77, 0x50, 0xbf, 0xc1, 0x2a, 0x0b, 0x1d, 0x58, 0xdd, 0x0d, 0x37, + 0xf4, 0x36, 0x25, 0xb0, 0xee, 0x6e, 0x38, 0xfe, 0x75, 0x40, 0x4c, 0xe4, 0xc5, 0x8d, 0x9c, 0x31, + 0x2f, 0x90, 0xc1, 0xa2, 0x88, 0x9b, 0x4f, 0xa1, 0x33, 0xd0, 0xf2, 0x35, 0x2d, 0x3e, 0x10, 0xbe, + 0x49, 0x5b, 0x8b, 0x0c, 0xb4, 0x7c, 0x7a, 0x44, 0xee, 0x07, 0xcc, 0xe7, 0xf3, 0x8b, 0x04, 0xcb, + 0x5c, 0x2e, 0x3d, 0x44, 0xf9, 0xa3, 0xb2, 0x70, 0x56, 0x49, 0x58, 0x85, 0xda, 0x93, 0xc8, 0x3d, + 0x8c, 0xba, 0x27, 0x91, 0xdb, 0x58, 0x85, 0xe8, 0x13, 0xb2, 0xdb, 0xde, 0x87, 0x2c, 0xea, 0x07, + 0x65, 0xe1, 0xb4, 0x29, 0x68, 0x03, 0x42, 0x8e, 0xcf, 0xfb, 0x34, 0xbf, 0x88, 0x42, 0xdf, 0x13, + 0xf2, 0x7b, 0xb5, 0xbc, 0x45, 0x41, 0x1b, 0x18, 0x5f, 0xf5, 0x89, 0x89, 0x7f, 0x28, 0xa2, 0x94, + 0x98, 0x6c, 0x13, 0xcf, 0x78, 0x1e, 0x6b, 0x85, 0xdc, 0xc4, 0x41, 0xf3, 0xe8, 0x57, 0x64, 0x8f, + 0x2d, 0x9b, 0xcb, 0x65, 0x2e, 0x5a, 0x82, 0x4c, 0x48, 0xd3, 0x7d, 0x58, 0x16, 0xce, 0x0a, 0x07, + 0x2b, 0x08, 0xfd, 0x8c, 0x6c, 0x2b, 0x0c, 0x6b, 0x44, 0x36, 0x7c, 0xd3, 0xbd, 0x5f, 0x16, 0x8e, + 0x4e, 0x80, 0xee, 0x0a, 0x21, 0xfe, 0x43, 0x01, 0xf3, 0x59, 0xf8, 0x53, 0xd5, 0xde, 0x51, 0xa8, + 0x11, 0xa0, 0xbb, 0xa2, 0x51, 0x23, 0x80, 0x95, 0x2f, 0x53, 0x06, 0x1b, 0x75, 0x05, 0x42, 0x6d, + 0x8a, 0xfe, 0x9f, 0xc8, 0xbd, 0xca, 0xfc, 0x30, 0x65, 0xff, 0x5f, 0x62, 0x50, 0x59, 0xee, 0xf4, + 0xfa, 0xc6, 0xee, 0xbd, 0xbe, 0xb1, 0x7b, 0x77, 0x37, 0xb6, 0xf1, 0xcb, 0xc2, 0x36, 0xfe, 0x5a, + 0xd8, 0xc6, 0xd5, 0xc2, 0x36, 0xae, 0x17, 0xb6, 0xf1, 0xcf, 0xc2, 0x36, 0xfe, 0x5d, 0xd8, 0xbd, + 0xbb, 0x85, 0x6d, 0xfc, 0x7e, 0x6b, 0xf7, 0xae, 0x6f, 0xed, 0xde, 0xeb, 0x5b, 0xbb, 0xf7, 0xe3, + 0x07, 0xcd, 0x6f, 0xaf, 0xc4, 0x3b, 0xf5, 0x62, 0x6f, 0x12, 0xf1, 0xf3, 0x70, 0xd2, 0xf5, 0xf1, + 0x36, 0x1d, 0xe2, 0x17, 0xd8, 0x27, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff, 0xb1, 0xee, 0x30, 0x71, + 0xdb, 0x09, 0x00, 0x00, } func (this *Result) Equal(that interface{}) bool { @@ -964,7 +973,10 @@ func (this *Cache) Equal(that interface{}) bool { if this.EntriesStored != that1.EntriesStored { return false } - if this.BytesTransferred != that1.BytesTransferred { + if this.BytesReceived != that1.BytesReceived { + return false + } + if this.BytesSent != that1.BytesSent { return false } if this.Requests != that1.Requests { @@ -1070,12 +1082,13 @@ func (this *Cache) GoString() string { if this == nil { return "nil" } - s := make([]string, 0, 9) + s := make([]string, 0, 10) s = append(s, "&stats.Cache{") s = append(s, "EntriesFound: "+fmt.Sprintf("%#v", this.EntriesFound)+",\n") s = append(s, "EntriesRequested: "+fmt.Sprintf("%#v", this.EntriesRequested)+",\n") s = append(s, "EntriesStored: "+fmt.Sprintf("%#v", this.EntriesStored)+",\n") - s = append(s, "BytesTransferred: "+fmt.Sprintf("%#v", this.BytesTransferred)+",\n") + s = append(s, "BytesReceived: "+fmt.Sprintf("%#v", this.BytesReceived)+",\n") + s = append(s, "BytesSent: "+fmt.Sprintf("%#v", this.BytesSent)+",\n") s = append(s, "Requests: "+fmt.Sprintf("%#v", this.Requests)+",\n") s = append(s, "}") return strings.Join(s, "") @@ -1479,10 +1492,15 @@ func (m *Cache) MarshalToSizedBuffer(dAtA []byte) (int, error) { if m.Requests != 0 { i = encodeVarintStats(dAtA, i, uint64(m.Requests)) i-- + dAtA[i] = 0x30 + } + if m.BytesSent != 0 { + i = encodeVarintStats(dAtA, i, uint64(m.BytesSent)) + i-- dAtA[i] = 0x28 } - if m.BytesTransferred != 0 { - i = encodeVarintStats(dAtA, i, uint64(m.BytesTransferred)) + if m.BytesReceived != 0 { + i = encodeVarintStats(dAtA, i, uint64(m.BytesReceived)) i-- dAtA[i] = 0x20 } @@ -1676,8 +1694,11 @@ func (m *Cache) Size() (n int) { if m.EntriesStored != 0 { n += 1 + sovStats(uint64(m.EntriesStored)) } - if m.BytesTransferred != 0 { - n += 1 + sovStats(uint64(m.BytesTransferred)) + if m.BytesReceived != 0 { + n += 1 + sovStats(uint64(m.BytesReceived)) + } + if m.BytesSent != 0 { + n += 1 + sovStats(uint64(m.BytesSent)) } if m.Requests != 0 { n += 1 + sovStats(uint64(m.Requests)) @@ -1793,7 +1814,8 @@ func (this *Cache) String() string { `EntriesFound:` + fmt.Sprintf("%v", this.EntriesFound) + `,`, `EntriesRequested:` + fmt.Sprintf("%v", this.EntriesRequested) + `,`, `EntriesStored:` + fmt.Sprintf("%v", this.EntriesStored) + `,`, - `BytesTransferred:` + fmt.Sprintf("%v", this.BytesTransferred) + `,`, + `BytesReceived:` + fmt.Sprintf("%v", this.BytesReceived) + `,`, + `BytesSent:` + fmt.Sprintf("%v", this.BytesSent) + `,`, `Requests:` + fmt.Sprintf("%v", this.Requests) + `,`, `}`, }, "") @@ -2979,9 +3001,9 @@ func (m *Cache) Unmarshal(dAtA []byte) error { } case 4: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field BytesTransferred", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field BytesReceived", wireType) } - m.BytesTransferred = 0 + m.BytesReceived = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowStats @@ -2991,12 +3013,31 @@ func (m *Cache) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.BytesTransferred |= int64(b&0x7F) << shift + m.BytesReceived |= int64(b&0x7F) << shift if b < 0x80 { break } } case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BytesSent", wireType) + } + m.BytesSent = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStats + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.BytesSent |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Requests", wireType) } diff --git a/pkg/logqlmodel/stats/stats.proto b/pkg/logqlmodel/stats/stats.proto index 27615021e1e8c..d376214c27de5 100644 --- a/pkg/logqlmodel/stats/stats.proto +++ b/pkg/logqlmodel/stats/stats.proto @@ -123,6 +123,7 @@ message Cache { int32 entriesFound = 1 [(gogoproto.jsontag) = "entriesFound"]; int32 entriesRequested = 2 [(gogoproto.jsontag) = "entriesRequested"]; int32 entriesStored = 3 [(gogoproto.jsontag) = "entriesStored"]; - int64 bytesTransferred = 4 [(gogoproto.jsontag) = "bytesTransferred"]; - int32 requests = 5 [(gogoproto.jsontag) = "requests"]; + int64 bytesReceived = 4 [(gogoproto.jsontag) = "bytesReceived"]; + int64 bytesSent = 5 [(gogoproto.jsontag) = "bytesSent"]; + int32 requests = 6 [(gogoproto.jsontag) = "requests"]; } diff --git a/pkg/storage/chunk/cache/cache.go b/pkg/storage/chunk/cache/cache.go index d2f255592c6ad..8fe3d0e63aaae 100644 --- a/pkg/storage/chunk/cache/cache.go +++ b/pkg/storage/chunk/cache/cache.go @@ -100,7 +100,7 @@ func New(cfg Config, reg prometheus.Registerer, logger log.Logger, cacheType sta } if cache := NewFifoCache(cfg.Prefix+"fifocache", cfg.Fifocache, reg, logger, cacheType); cache != nil { - caches = append(caches, Instrument(cfg.Prefix+"fifocache", cache, reg)) + caches = append(caches, CollectStats(Instrument(cfg.Prefix+"fifocache", cache, reg))) } } @@ -117,7 +117,7 @@ func New(cfg Config, reg prometheus.Registerer, logger log.Logger, cacheType sta cache := NewMemcached(cfg.Memcache, client, cfg.Prefix, reg, logger, cacheType) cacheName := cfg.Prefix + "memcache" - caches = append(caches, NewBackground(cacheName, cfg.Background, Instrument(cacheName, cache, reg), reg)) + caches = append(caches, CollectStats(NewBackground(cacheName, cfg.Background, Instrument(cacheName, cache, reg), reg))) } if IsRedisSet(cfg) { @@ -130,7 +130,7 @@ func New(cfg Config, reg prometheus.Registerer, logger log.Logger, cacheType sta return nil, fmt.Errorf("redis client setup failed: %w", err) } cache := NewRedisCache(cacheName, client, logger, cacheType) - caches = append(caches, NewBackground(cacheName, cfg.Background, Instrument(cacheName, cache, reg), reg)) + caches = append(caches, CollectStats(NewBackground(cacheName, cfg.Background, Instrument(cacheName, cache, reg), reg))) } cache := NewTiered(caches) diff --git a/pkg/storage/chunk/cache/instrumented.go b/pkg/storage/chunk/cache/instrumented.go index c1716a7cb21f9..b9b32cbc7afd8 100644 --- a/pkg/storage/chunk/cache/instrumented.go +++ b/pkg/storage/chunk/cache/instrumented.go @@ -9,8 +9,6 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" instr "github.com/weaveworks/common/instrument" - - "github.com/grafana/loki/pkg/logqlmodel/stats" ) // Instrument returns an instrumented cache. @@ -72,8 +70,6 @@ func (i *instrumentedCache) Store(ctx context.Context, keys []string, bufs [][]b i.storedValueSize.Observe(float64(len(bufs[j]))) } - stats.FromContext(ctx).AddCacheEntriesStored(i.Cache.GetCacheType(), len(keys)) - method := i.name + ".store" return instr.CollectedRequest(ctx, method, i.requestDuration, instr.ErrorCode, func(ctx context.Context) error { sp := ot.SpanFromContext(ctx) @@ -96,9 +92,6 @@ func (i *instrumentedCache) Fetch(ctx context.Context, keys []string) ([]string, method = i.name + ".fetch" ) - st := stats.FromContext(ctx) - st.AddCacheRequest(i.Cache.GetCacheType(), 1) - err := instr.CollectedRequest(ctx, method, i.requestDuration, instr.ErrorCode, func(ctx context.Context) error { sp := ot.SpanFromContext(ctx) sp.LogFields(otlog.Int("keys requested", len(keys))) @@ -113,14 +106,8 @@ func (i *instrumentedCache) Fetch(ctx context.Context, keys []string) ([]string, i.fetchedKeys.Add(float64(len(keys))) i.hits.Add(float64(len(found))) - - st.AddCacheEntriesFound(i.Cache.GetCacheType(), len(found)) - st.AddCacheEntriesRequested(i.Cache.GetCacheType(), len(keys)) - for j := range bufs { - size := len(bufs[j]) - i.fetchedValueSize.Observe(float64(size)) - st.AddCacheBytesTransferred(i.Cache.GetCacheType(), size) + i.fetchedValueSize.Observe(float64(len(bufs[j]))) } return found, bufs, missing, err diff --git a/pkg/storage/chunk/cache/stats.go b/pkg/storage/chunk/cache/stats.go new file mode 100644 index 0000000000000..9964532ad8456 --- /dev/null +++ b/pkg/storage/chunk/cache/stats.go @@ -0,0 +1,53 @@ +package cache + +import ( + "context" + + "github.com/grafana/loki/pkg/logqlmodel/stats" +) + +type statsCollector struct { + Cache +} + +// CollectStats returns a new Cache that keeps various statistics on cache usage. +func CollectStats(cache Cache) Cache { + return &statsCollector{ + Cache: cache, + } +} + +func (s statsCollector) Store(ctx context.Context, keys []string, bufs [][]byte) error { + st := stats.FromContext(ctx) + st.AddCacheRequest(s.Cache.GetCacheType(), 1) + + // we blindly count the number of keys to be stored since we can't know if these will actually be written back to + // the cache successfully if cache.backgroundCache is in use + st.AddCacheEntriesStored(s.Cache.GetCacheType(), len(keys)) + + return s.Cache.Store(ctx, keys, bufs) +} + +func (s statsCollector) Fetch(ctx context.Context, keys []string) (found []string, bufs [][]byte, missing []string, err error) { + st := stats.FromContext(ctx) + st.AddCacheRequest(s.Cache.GetCacheType(), 1) + + found, bufs, missing, err = s.Cache.Fetch(ctx, keys) + + st.AddCacheEntriesFound(s.Cache.GetCacheType(), len(found)) + st.AddCacheEntriesRequested(s.Cache.GetCacheType(), len(keys)) + + for j := range bufs { + st.AddCacheBytesRetrieved(s.Cache.GetCacheType(), len(bufs[j])) + } + + return found, bufs, missing, err +} + +func (s statsCollector) Stop() { + s.Cache.Stop() +} + +func (s statsCollector) GetCacheType() stats.CacheType { + return s.Cache.GetCacheType() +} diff --git a/pkg/storage/chunk/fetcher/fetcher.go b/pkg/storage/chunk/fetcher/fetcher.go index 94e7e82b76869..fa4ed43619141 100644 --- a/pkg/storage/chunk/fetcher/fetcher.go +++ b/pkg/storage/chunk/fetcher/fetcher.go @@ -10,6 +10,7 @@ import ( "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/prometheus/promql" + "github.com/grafana/loki/pkg/logqlmodel/stats" "github.com/grafana/loki/pkg/storage/chunk" "github.com/grafana/loki/pkg/storage/chunk/cache" "github.com/grafana/loki/pkg/storage/chunk/client" @@ -182,6 +183,17 @@ func (c *Fetcher) FetchChunks(ctx context.Context, chunks []chunk.Chunk, keys [] fromStorage, err = c.storage.GetChunks(ctx, missing) } + // normally these stats would be collected by the cache.statsCollector wrapper, but chunks are written back + // to the cache asynchronously in the background and we lose the context + var bytes int + for _, c := range fromStorage { + bytes += c.Size() + } + + st := stats.FromContext(ctx) + st.AddCacheEntriesStored(stats.ChunkCache, len(fromStorage)) + st.AddCacheBytesSent(stats.ChunkCache, bytes) + // Always cache any chunks we did get if cacheErr := c.writeBackCacheAsync(fromStorage); cacheErr != nil { if cacheErr == errAsyncBufferFull { diff --git a/pkg/storage/store.go b/pkg/storage/store.go index 7a22ec9655973..b5fe10113027f 100644 --- a/pkg/storage/store.go +++ b/pkg/storage/store.go @@ -153,7 +153,7 @@ func (s *store) init() error { if err != nil { return err } - f, err := fetcher.New(s.chunksCache, s.storeCfg.ChunkCacheStubs(), s.schemaCfg, chunkClient, s.storeCfg.ChunkCacheConfig.AsyncCacheWriteBackConcurrency, s.storeCfg.ChunkCacheConfig.AsyncCacheWriteBackBufferSize) + f, err := fetcher.New(cache.CollectStats(s.chunksCache), s.storeCfg.ChunkCacheStubs(), s.schemaCfg, chunkClient, s.storeCfg.ChunkCacheConfig.AsyncCacheWriteBackConcurrency, s.storeCfg.ChunkCacheConfig.AsyncCacheWriteBackBufferSize) if err != nil { return err } From b966286c7ea892a1e3e522e67777e9f33dec4461 Mon Sep 17 00:00:00 2001 From: Danny Kopping Date: Tue, 7 Jun 2022 14:51:44 +0200 Subject: [PATCH 11/11] Fixing tests Signed-off-by: Danny Kopping --- pkg/logql/metrics_test.go | 2 +- pkg/logqlmodel/stats/context_test.go | 16 +++++++++----- pkg/querier/queryrange/codec_test.go | 9 +++++--- pkg/querier/queryrange/prometheus_test.go | 9 +++++--- pkg/util/marshal/legacy/marshal_test.go | 9 +++++--- pkg/util/marshal/marshal_test.go | 27 +++++++++++++++-------- 6 files changed, 47 insertions(+), 25 deletions(-) diff --git a/pkg/logql/metrics_test.go b/pkg/logql/metrics_test.go index fc1acfad8fa4f..99064b2d32415 100644 --- a/pkg/logql/metrics_test.go +++ b/pkg/logql/metrics_test.go @@ -84,7 +84,7 @@ func TestLogSlowQuery(t *testing.T) { }, logqlmodel.Streams{logproto.Stream{Entries: make([]logproto.Entry, 10)}}) require.Equal(t, fmt.Sprintf( - "level=info org_id=foo traceID=%s latency=slow query=\"{foo=\\\"bar\\\"} |= \\\"buzz\\\"\" query_type=filter range_type=range length=1h0m0s step=1m0s duration=25.25s status=200 limit=1000 returned_lines=10 throughput=100kB total_bytes=100kB total_entries=10 queue_time=2ns subqueries=0 cached_chunks_req=0 cached_chunks_hit=0 cached_chunks_bytes=0 cached_indexes_req=0 cached_indexes_hit=0 cached_results_req=0 cached_results_hit=0 source=logvolhist feature=beta\n", + "level=info org_id=foo traceID=%s latency=slow query=\"{foo=\\\"bar\\\"} |= \\\"buzz\\\"\" query_type=filter range_type=range length=1h0m0s step=1m0s duration=25.25s status=200 limit=1000 returned_lines=10 throughput=100kB total_bytes=100kB total_entries=10 queue_time=2ns subqueries=0 cache_chunk_req=0 cache_chunk_hit=0 cache_chunk_bytes_stored=0 cache_chunk_bytes_fetched=0 cache_index_req=0 cache_index_hit=0 cache_result_req=0 cache_result_hit=0 source=logvolhist feature=beta\n", sp.Context().(jaeger.SpanContext).SpanID().String(), ), buf.String()) diff --git a/pkg/logqlmodel/stats/context_test.go b/pkg/logqlmodel/stats/context_test.go index 02cec0e2bb217..220c81980c31b 100644 --- a/pkg/logqlmodel/stats/context_test.go +++ b/pkg/logqlmodel/stats/context_test.go @@ -198,8 +198,9 @@ func TestResult_Merge(t *testing.T) { }, Caches: Caches{ Chunk: Cache{ - Requests: 5, - BytesTransferred: 1024, + Requests: 5, + BytesReceived: 1024, + BytesSent: 512, }, Index: Cache{ EntriesRequested: 22, @@ -259,8 +260,9 @@ func TestResult_Merge(t *testing.T) { }, Caches: Caches{ Chunk: Cache{ - Requests: 2 * 5, - BytesTransferred: 2 * 1024, + Requests: 2 * 5, + BytesReceived: 2 * 1024, + BytesSent: 2 * 512, }, Index: Cache{ EntriesRequested: 2 * 22, @@ -321,12 +323,14 @@ func TestCaches(t *testing.T) { statsCtx.AddCacheEntriesStored(ResultCache, 3) statsCtx.AddCacheEntriesRequested(IndexCache, 22) statsCtx.AddCacheBytesRetrieved(ChunkCache, 1024) + statsCtx.AddCacheBytesSent(ChunkCache, 512) statsCtx.AddCacheEntriesFound(IndexCache, 2) require.Equal(t, Caches{ Chunk: Cache{ - Requests: 5, - BytesTransferred: 1024, + Requests: 5, + BytesReceived: 1024, + BytesSent: 512, }, Index: Cache{ EntriesRequested: 22, diff --git a/pkg/querier/queryrange/codec_test.go b/pkg/querier/queryrange/codec_test.go index 913494b7fe2b8..71e5f9a0f52e4 100644 --- a/pkg/querier/queryrange/codec_test.go +++ b/pkg/querier/queryrange/codec_test.go @@ -932,21 +932,24 @@ var ( "entriesFound": 0, "entriesRequested": 0, "entriesStored": 0, - "bytesTransferred": 0, + "bytesReceived": 0, + "bytesSent": 0, "requests": 0 }, "index": { "entriesFound": 0, "entriesRequested": 0, "entriesStored": 0, - "bytesTransferred": 0, + "bytesReceived": 0, + "bytesSent": 0, "requests": 0 }, "result": { "entriesFound": 0, "entriesRequested": 0, "entriesStored": 0, - "bytesTransferred": 0, + "bytesReceived": 0, + "bytesSent": 0, "requests": 0 } }, diff --git a/pkg/querier/queryrange/prometheus_test.go b/pkg/querier/queryrange/prometheus_test.go index 3aefd4e1abd4a..84bd2112b155f 100644 --- a/pkg/querier/queryrange/prometheus_test.go +++ b/pkg/querier/queryrange/prometheus_test.go @@ -52,21 +52,24 @@ var emptyStats = `"stats": { "entriesFound": 0, "entriesRequested": 0, "entriesStored": 0, - "bytesTransferred": 0, + "bytesReceived": 0, + "bytesSent": 0, "requests": 0 }, "index": { "entriesFound": 0, "entriesRequested": 0, "entriesStored": 0, - "bytesTransferred": 0, + "bytesReceived": 0, + "bytesSent": 0, "requests": 0 }, "result": { "entriesFound": 0, "entriesRequested": 0, "entriesStored": 0, - "bytesTransferred": 0, + "bytesReceived": 0, + "bytesSent": 0, "requests": 0 } }, diff --git a/pkg/util/marshal/legacy/marshal_test.go b/pkg/util/marshal/legacy/marshal_test.go index 074bdf4bebdc2..cf8a18b7bbd41 100644 --- a/pkg/util/marshal/legacy/marshal_test.go +++ b/pkg/util/marshal/legacy/marshal_test.go @@ -83,21 +83,24 @@ var queryTests = []struct { "entriesFound": 0, "entriesRequested": 0, "entriesStored": 0, - "bytesTransferred": 0, + "bytesReceived": 0, + "bytesSent": 0, "requests": 0 }, "index": { "entriesFound": 0, "entriesRequested": 0, "entriesStored": 0, - "bytesTransferred": 0, + "bytesReceived": 0, + "bytesSent": 0, "requests": 0 }, "result": { "entriesFound": 0, "entriesRequested": 0, "entriesStored": 0, - "bytesTransferred": 0, + "bytesReceived": 0, + "bytesSent": 0, "requests": 0 } }, diff --git a/pkg/util/marshal/marshal_test.go b/pkg/util/marshal/marshal_test.go index 3a95a77685c03..38b7cc74dca6e 100644 --- a/pkg/util/marshal/marshal_test.go +++ b/pkg/util/marshal/marshal_test.go @@ -89,21 +89,24 @@ var queryTests = []struct { "entriesFound": 0, "entriesRequested": 0, "entriesStored": 0, - "bytesTransferred": 0, + "bytesReceived": 0, + "bytesSent": 0, "requests": 0 }, "index": { "entriesFound": 0, "entriesRequested": 0, "entriesStored": 0, - "bytesTransferred": 0, + "bytesReceived": 0, + "bytesSent": 0, "requests": 0 }, "result": { "entriesFound": 0, "entriesRequested": 0, "entriesStored": 0, - "bytesTransferred": 0, + "bytesReceived": 0, + "bytesSent": 0, "requests": 0 } }, @@ -222,21 +225,24 @@ var queryTests = []struct { "entriesFound": 0, "entriesRequested": 0, "entriesStored": 0, - "bytesTransferred": 0, + "bytesReceived": 0, + "bytesSent": 0, "requests": 0 }, "index": { "entriesFound": 0, "entriesRequested": 0, "entriesStored": 0, - "bytesTransferred": 0, + "bytesReceived": 0, + "bytesSent": 0, "requests": 0 }, "result": { "entriesFound": 0, "entriesRequested": 0, "entriesStored": 0, - "bytesTransferred": 0, + "bytesReceived": 0, + "bytesSent": 0, "requests": 0 } }, @@ -372,21 +378,24 @@ var queryTests = []struct { "entriesFound": 0, "entriesRequested": 0, "entriesStored": 0, - "bytesTransferred": 0, + "bytesReceived": 0, + "bytesSent": 0, "requests": 0 }, "index": { "entriesFound": 0, "entriesRequested": 0, "entriesStored": 0, - "bytesTransferred": 0, + "bytesReceived": 0, + "bytesSent": 0, "requests": 0 }, "result": { "entriesFound": 0, "entriesRequested": 0, "entriesStored": 0, - "bytesTransferred": 0, + "bytesReceived": 0, + "bytesSent": 0, "requests": 0 } },