diff --git a/Makefile b/Makefile index fd69e72ce2..7164767a96 100644 --- a/Makefile +++ b/Makefile @@ -250,7 +250,7 @@ clean: ## Delete intermediate build artifacts .PHONY: reference-help reference-help: ## Generates the reference help documentation. -reference-help: build +reference-help: go/bin @(./pyroscope -h || true) > cmd/pyroscope/help.txt.tmpl @(./pyroscope -help-all || true) > cmd/pyroscope/help-all.txt.tmpl diff --git a/api/gen/proto/go/ingester/v1/ingester.pb.go b/api/gen/proto/go/ingester/v1/ingester.pb.go index 571d8b6ded..fa7e443cfb 100644 --- a/api/gen/proto/go/ingester/v1/ingester.pb.go +++ b/api/gen/proto/go/ingester/v1/ingester.pb.go @@ -1654,6 +1654,187 @@ func (x *BlockHints) GetDeduplication() bool { return false } +type GetBlockStatsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ulids []string `protobuf:"bytes,1,rep,name=ulids,proto3" json:"ulids,omitempty"` +} + +func (x *GetBlockStatsRequest) Reset() { + *x = GetBlockStatsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ingester_v1_ingester_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBlockStatsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBlockStatsRequest) ProtoMessage() {} + +func (x *GetBlockStatsRequest) ProtoReflect() protoreflect.Message { + mi := &file_ingester_v1_ingester_proto_msgTypes[26] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetBlockStatsRequest.ProtoReflect.Descriptor instead. +func (*GetBlockStatsRequest) Descriptor() ([]byte, []int) { + return file_ingester_v1_ingester_proto_rawDescGZIP(), []int{26} +} + +func (x *GetBlockStatsRequest) GetUlids() []string { + if x != nil { + return x.Ulids + } + return nil +} + +type GetBlockStatsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + BlockStats []*BlockStats `protobuf:"bytes,1,rep,name=block_stats,json=blockStats,proto3" json:"block_stats,omitempty"` +} + +func (x *GetBlockStatsResponse) Reset() { + *x = GetBlockStatsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ingester_v1_ingester_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBlockStatsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBlockStatsResponse) ProtoMessage() {} + +func (x *GetBlockStatsResponse) ProtoReflect() protoreflect.Message { + mi := &file_ingester_v1_ingester_proto_msgTypes[27] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetBlockStatsResponse.ProtoReflect.Descriptor instead. +func (*GetBlockStatsResponse) Descriptor() ([]byte, []int) { + return file_ingester_v1_ingester_proto_rawDescGZIP(), []int{27} +} + +func (x *GetBlockStatsResponse) GetBlockStats() []*BlockStats { + if x != nil { + return x.BlockStats + } + return nil +} + +type BlockStats struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SeriesCount uint64 `protobuf:"varint,2,opt,name=series_count,json=seriesCount,proto3" json:"series_count,omitempty"` + ProfileCount uint64 `protobuf:"varint,3,opt,name=profile_count,json=profileCount,proto3" json:"profile_count,omitempty"` + SampleCount uint64 `protobuf:"varint,4,opt,name=sample_count,json=sampleCount,proto3" json:"sample_count,omitempty"` + IndexBytes uint64 `protobuf:"varint,5,opt,name=index_bytes,json=indexBytes,proto3" json:"index_bytes,omitempty"` + ProfileBytes uint64 `protobuf:"varint,6,opt,name=profile_bytes,json=profileBytes,proto3" json:"profile_bytes,omitempty"` + SymbolBytes uint64 `protobuf:"varint,7,opt,name=symbol_bytes,json=symbolBytes,proto3" json:"symbol_bytes,omitempty"` +} + +func (x *BlockStats) Reset() { + *x = BlockStats{} + if protoimpl.UnsafeEnabled { + mi := &file_ingester_v1_ingester_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BlockStats) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BlockStats) ProtoMessage() {} + +func (x *BlockStats) ProtoReflect() protoreflect.Message { + mi := &file_ingester_v1_ingester_proto_msgTypes[28] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BlockStats.ProtoReflect.Descriptor instead. +func (*BlockStats) Descriptor() ([]byte, []int) { + return file_ingester_v1_ingester_proto_rawDescGZIP(), []int{28} +} + +func (x *BlockStats) GetSeriesCount() uint64 { + if x != nil { + return x.SeriesCount + } + return 0 +} + +func (x *BlockStats) GetProfileCount() uint64 { + if x != nil { + return x.ProfileCount + } + return 0 +} + +func (x *BlockStats) GetSampleCount() uint64 { + if x != nil { + return x.SampleCount + } + return 0 +} + +func (x *BlockStats) GetIndexBytes() uint64 { + if x != nil { + return x.IndexBytes + } + return 0 +} + +func (x *BlockStats) GetProfileBytes() uint64 { + if x != nil { + return x.ProfileBytes + } + return 0 +} + +func (x *BlockStats) GetSymbolBytes() uint64 { + if x != nil { + return x.SymbolBytes + } + return 0 +} + var File_ingester_v1_ingester_proto protoreflect.FileDescriptor var file_ingester_v1_ingester_proto_rawDesc = []byte{ @@ -1877,93 +2058,121 @@ var file_ingester_v1_ingester_proto_rawDesc = []byte{ 0x6c, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x75, 0x6c, 0x69, 0x64, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x64, 0x65, 0x64, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x64, 0x65, 0x64, 0x75, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2a, 0x6b, 0x0a, 0x16, 0x53, 0x74, 0x61, 0x63, 0x6b, - 0x74, 0x72, 0x61, 0x63, 0x65, 0x73, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, - 0x74, 0x12, 0x1c, 0x0a, 0x18, 0x4d, 0x45, 0x52, 0x47, 0x45, 0x5f, 0x46, 0x4f, 0x52, 0x4d, 0x41, - 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, - 0x1c, 0x0a, 0x18, 0x4d, 0x45, 0x52, 0x47, 0x45, 0x5f, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x5f, - 0x53, 0x54, 0x41, 0x43, 0x4b, 0x54, 0x52, 0x41, 0x43, 0x45, 0x53, 0x10, 0x01, 0x12, 0x15, 0x0a, - 0x11, 0x4d, 0x45, 0x52, 0x47, 0x45, 0x5f, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x5f, 0x54, 0x52, - 0x45, 0x45, 0x10, 0x02, 0x32, 0xb6, 0x08, 0x0a, 0x0f, 0x49, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, - 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x50, 0x75, 0x73, 0x68, - 0x12, 0x14, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x2e, 0x76, 0x31, - 0x2e, 0x50, 0x75, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x4c, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x1c, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x74, - 0x79, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x49, 0x0a, - 0x0a, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x1b, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x66, - 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x20, 0x2e, 0x69, 0x6e, 0x67, 0x65, 0x73, - 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x54, 0x79, - 0x70, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x69, 0x6e, 0x67, - 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, - 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x43, 0x0a, 0x06, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, 0x1a, 0x2e, 0x69, 0x6e, 0x67, 0x65, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2c, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x14, 0x0a, 0x05, 0x75, 0x6c, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, + 0x75, 0x6c, 0x69, 0x64, 0x73, 0x22, 0x51, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, + 0x6b, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, + 0x0a, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x0a, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x73, 0x22, 0xe0, 0x01, 0x0a, 0x0a, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x69, 0x65, + 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x73, + 0x65, 0x72, 0x69, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, + 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, + 0x21, 0x0a, 0x0c, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x62, 0x79, 0x74, 0x65, + 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x42, 0x79, + 0x74, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x62, + 0x79, 0x74, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x66, + 0x69, 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x79, 0x6d, 0x62, + 0x6f, 0x6c, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, + 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x2a, 0x6b, 0x0a, 0x16, 0x53, + 0x74, 0x61, 0x63, 0x6b, 0x74, 0x72, 0x61, 0x63, 0x65, 0x73, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x46, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x1c, 0x0a, 0x18, 0x4d, 0x45, 0x52, 0x47, 0x45, 0x5f, 0x46, + 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, + 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x4d, 0x45, 0x52, 0x47, 0x45, 0x5f, 0x46, 0x4f, 0x52, + 0x4d, 0x41, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x43, 0x4b, 0x54, 0x52, 0x41, 0x43, 0x45, 0x53, 0x10, + 0x01, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x45, 0x52, 0x47, 0x45, 0x5f, 0x46, 0x4f, 0x52, 0x4d, 0x41, + 0x54, 0x5f, 0x54, 0x52, 0x45, 0x45, 0x10, 0x02, 0x32, 0x90, 0x09, 0x0a, 0x0f, 0x49, 0x6e, 0x67, + 0x65, 0x73, 0x74, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x35, 0x0a, 0x04, + 0x50, 0x75, 0x73, 0x68, 0x12, 0x14, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x50, + 0x75, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x70, 0x75, 0x73, + 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x73, 0x12, 0x1c, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x61, + 0x62, 0x65, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x61, 0x62, 0x65, + 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x49, 0x0a, 0x0a, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, + 0x1b, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, + 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x4e, 0x61, 0x6d, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x0c, + 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x20, 0x2e, 0x69, + 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x66, 0x69, + 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, + 0x2e, 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, + 0x66, 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x06, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, 0x1a, 0x2e, + 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x69, + 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x05, 0x46, 0x6c, 0x75, 0x73, 0x68, 0x12, 0x19, 0x2e, - 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x6c, 0x75, 0x73, - 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x69, 0x6e, 0x67, 0x65, 0x73, - 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x6c, 0x75, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7d, 0x0a, 0x18, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x50, - 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x74, 0x72, 0x61, 0x63, - 0x65, 0x73, 0x12, 0x2c, 0x2e, 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x53, 0x74, - 0x61, 0x63, 0x6b, 0x74, 0x72, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x2d, 0x2e, 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, - 0x65, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x53, 0x74, 0x61, 0x63, - 0x6b, 0x74, 0x72, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x6e, 0x0a, 0x13, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x50, 0x72, - 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x27, 0x2e, 0x69, - 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x72, 0x67, 0x65, - 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, - 0x73, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x6b, 0x0a, 0x12, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x50, 0x72, - 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x12, 0x26, 0x2e, 0x69, 0x6e, - 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x50, - 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x2e, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x50, - 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, - 0x30, 0x01, 0x12, 0x65, 0x0a, 0x10, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x50, - 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x24, 0x2e, 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, - 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x50, 0x72, - 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x69, - 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x72, 0x67, 0x65, - 0x53, 0x70, 0x61, 0x6e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x58, 0x0a, 0x0d, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x21, 0x2e, 0x69, 0x6e, 0x67, - 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, - 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x63, - 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, - 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x20, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x76, - 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x74, - 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xb3, 0x01, - 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x2e, 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x42, 0x0d, 0x49, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x50, 0x01, 0x5a, 0x44, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, - 0x72, 0x61, 0x66, 0x61, 0x6e, 0x61, 0x2f, 0x70, 0x79, 0x72, 0x6f, 0x73, 0x63, 0x6f, 0x70, 0x65, - 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, - 0x6f, 0x2f, 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x69, 0x6e, - 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x49, 0x58, 0x58, 0xaa, 0x02, - 0x0b, 0x49, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0b, 0x49, - 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x17, 0x49, 0x6e, 0x67, - 0x65, 0x73, 0x74, 0x65, 0x72, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0c, 0x49, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x3a, - 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x05, 0x46, 0x6c, 0x75, 0x73, + 0x68, 0x12, 0x19, 0x2e, 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, + 0x46, 0x6c, 0x75, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x69, + 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x6c, 0x75, 0x73, 0x68, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7d, 0x0a, 0x18, 0x4d, 0x65, + 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x53, 0x74, 0x61, 0x63, 0x6b, + 0x74, 0x72, 0x61, 0x63, 0x65, 0x73, 0x12, 0x2c, 0x2e, 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, + 0x65, 0x73, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x74, 0x72, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, + 0x53, 0x74, 0x61, 0x63, 0x6b, 0x74, 0x72, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x6e, 0x0a, 0x13, 0x4d, 0x65, 0x72, + 0x67, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, + 0x12, 0x27, 0x2e, 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, + 0x65, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x4c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x69, 0x6e, 0x67, 0x65, + 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, + 0x66, 0x69, 0x6c, 0x65, 0x73, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x6b, 0x0a, 0x12, 0x4d, 0x65, 0x72, + 0x67, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x12, + 0x26, 0x2e, 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, + 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x50, 0x70, 0x72, 0x6f, 0x66, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, + 0x6c, 0x65, 0x73, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x65, 0x0a, 0x10, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x53, + 0x70, 0x61, 0x6e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x24, 0x2e, 0x69, 0x6e, 0x67, + 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x53, 0x70, + 0x61, 0x6e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x25, 0x2e, 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, + 0x65, 0x72, 0x67, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x58, 0x0a, + 0x0d, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x21, + 0x2e, 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x22, 0x2e, 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x50, 0x72, + 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x20, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, + 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x58, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, + 0x74, 0x73, 0x12, 0x21, 0x2e, 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xb3, 0x01, 0x0a, 0x0f, + 0x63, 0x6f, 0x6d, 0x2e, 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x42, + 0x0d, 0x49, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, + 0x5a, 0x44, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, + 0x66, 0x61, 0x6e, 0x61, 0x2f, 0x70, 0x79, 0x72, 0x6f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, + 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x69, 0x6e, 0x67, 0x65, + 0x73, 0x74, 0x65, 0x72, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x49, 0x58, 0x58, 0xaa, 0x02, 0x0b, 0x49, + 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0b, 0x49, 0x6e, 0x67, + 0x65, 0x73, 0x74, 0x65, 0x72, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x17, 0x49, 0x6e, 0x67, 0x65, 0x73, + 0x74, 0x65, 0x72, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0xea, 0x02, 0x0c, 0x49, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x3a, 0x3a, 0x56, + 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1979,7 +2188,7 @@ func file_ingester_v1_ingester_proto_rawDescGZIP() []byte { } var file_ingester_v1_ingester_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_ingester_v1_ingester_proto_msgTypes = make([]protoimpl.MessageInfo, 26) +var file_ingester_v1_ingester_proto_msgTypes = make([]protoimpl.MessageInfo, 29) var file_ingester_v1_ingester_proto_goTypes = []interface{}{ (StacktracesMergeFormat)(0), // 0: ingester.v1.StacktracesMergeFormat (*ProfileTypesRequest)(nil), // 1: ingester.v1.ProfileTypesRequest @@ -2008,81 +2217,87 @@ var file_ingester_v1_ingester_proto_goTypes = []interface{}{ (*BlockMetadataResponse)(nil), // 24: ingester.v1.BlockMetadataResponse (*Hints)(nil), // 25: ingester.v1.Hints (*BlockHints)(nil), // 26: ingester.v1.BlockHints - (*v1.ProfileType)(nil), // 27: types.v1.ProfileType - (*v1.Labels)(nil), // 28: types.v1.Labels - (v1.TimeSeriesAggregationType)(0), // 29: types.v1.TimeSeriesAggregationType - (*v1.LabelPair)(nil), // 30: types.v1.LabelPair - (*v1.StackTraceSelector)(nil), // 31: types.v1.StackTraceSelector - (*v1.Series)(nil), // 32: types.v1.Series - (*v1.BlockInfo)(nil), // 33: types.v1.BlockInfo - (*v11.PushRequest)(nil), // 34: push.v1.PushRequest - (*v1.LabelValuesRequest)(nil), // 35: types.v1.LabelValuesRequest - (*v1.LabelNamesRequest)(nil), // 36: types.v1.LabelNamesRequest - (*v1.GetProfileStatsRequest)(nil), // 37: types.v1.GetProfileStatsRequest - (*v11.PushResponse)(nil), // 38: push.v1.PushResponse - (*v1.LabelValuesResponse)(nil), // 39: types.v1.LabelValuesResponse - (*v1.LabelNamesResponse)(nil), // 40: types.v1.LabelNamesResponse - (*v1.GetProfileStatsResponse)(nil), // 41: types.v1.GetProfileStatsResponse + (*GetBlockStatsRequest)(nil), // 27: ingester.v1.GetBlockStatsRequest + (*GetBlockStatsResponse)(nil), // 28: ingester.v1.GetBlockStatsResponse + (*BlockStats)(nil), // 29: ingester.v1.BlockStats + (*v1.ProfileType)(nil), // 30: types.v1.ProfileType + (*v1.Labels)(nil), // 31: types.v1.Labels + (v1.TimeSeriesAggregationType)(0), // 32: types.v1.TimeSeriesAggregationType + (*v1.LabelPair)(nil), // 33: types.v1.LabelPair + (*v1.StackTraceSelector)(nil), // 34: types.v1.StackTraceSelector + (*v1.Series)(nil), // 35: types.v1.Series + (*v1.BlockInfo)(nil), // 36: types.v1.BlockInfo + (*v11.PushRequest)(nil), // 37: push.v1.PushRequest + (*v1.LabelValuesRequest)(nil), // 38: types.v1.LabelValuesRequest + (*v1.LabelNamesRequest)(nil), // 39: types.v1.LabelNamesRequest + (*v1.GetProfileStatsRequest)(nil), // 40: types.v1.GetProfileStatsRequest + (*v11.PushResponse)(nil), // 41: push.v1.PushResponse + (*v1.LabelValuesResponse)(nil), // 42: types.v1.LabelValuesResponse + (*v1.LabelNamesResponse)(nil), // 43: types.v1.LabelNamesResponse + (*v1.GetProfileStatsResponse)(nil), // 44: types.v1.GetProfileStatsResponse } var file_ingester_v1_ingester_proto_depIdxs = []int32{ - 27, // 0: ingester.v1.ProfileTypesResponse.profile_types:type_name -> types.v1.ProfileType - 28, // 1: ingester.v1.SeriesResponse.labels_set:type_name -> types.v1.Labels - 27, // 2: ingester.v1.SelectProfilesRequest.type:type_name -> types.v1.ProfileType + 30, // 0: ingester.v1.ProfileTypesResponse.profile_types:type_name -> types.v1.ProfileType + 31, // 1: ingester.v1.SeriesResponse.labels_set:type_name -> types.v1.Labels + 30, // 2: ingester.v1.SelectProfilesRequest.type:type_name -> types.v1.ProfileType 25, // 3: ingester.v1.SelectProfilesRequest.hints:type_name -> ingester.v1.Hints - 29, // 4: ingester.v1.SelectProfilesRequest.aggregation:type_name -> types.v1.TimeSeriesAggregationType + 32, // 4: ingester.v1.SelectProfilesRequest.aggregation:type_name -> types.v1.TimeSeriesAggregationType 7, // 5: ingester.v1.MergeProfilesStacktracesRequest.request:type_name -> ingester.v1.SelectProfilesRequest 0, // 6: ingester.v1.MergeProfilesStacktracesResult.format:type_name -> ingester.v1.StacktracesMergeFormat 18, // 7: ingester.v1.MergeProfilesStacktracesResult.stacktraces:type_name -> ingester.v1.StacktraceSample 15, // 8: ingester.v1.MergeProfilesStacktracesResponse.selectedProfiles:type_name -> ingester.v1.ProfileSets 9, // 9: ingester.v1.MergeProfilesStacktracesResponse.result:type_name -> ingester.v1.MergeProfilesStacktracesResult - 27, // 10: ingester.v1.SelectSpanProfileRequest.type:type_name -> types.v1.ProfileType + 30, // 10: ingester.v1.SelectSpanProfileRequest.type:type_name -> types.v1.ProfileType 25, // 11: ingester.v1.SelectSpanProfileRequest.hints:type_name -> ingester.v1.Hints 11, // 12: ingester.v1.MergeSpanProfileRequest.request:type_name -> ingester.v1.SelectSpanProfileRequest 15, // 13: ingester.v1.MergeSpanProfileResponse.selectedProfiles:type_name -> ingester.v1.ProfileSets 14, // 14: ingester.v1.MergeSpanProfileResponse.result:type_name -> ingester.v1.MergeSpanProfileResult - 28, // 15: ingester.v1.ProfileSets.labelsSets:type_name -> types.v1.Labels + 31, // 15: ingester.v1.ProfileSets.labelsSets:type_name -> types.v1.Labels 16, // 16: ingester.v1.ProfileSets.profiles:type_name -> ingester.v1.SeriesProfile - 27, // 17: ingester.v1.Profile.type:type_name -> types.v1.ProfileType - 30, // 18: ingester.v1.Profile.labels:type_name -> types.v1.LabelPair + 30, // 17: ingester.v1.Profile.type:type_name -> types.v1.ProfileType + 33, // 18: ingester.v1.Profile.labels:type_name -> types.v1.LabelPair 18, // 19: ingester.v1.Profile.stacktraces:type_name -> ingester.v1.StacktraceSample 7, // 20: ingester.v1.MergeProfilesLabelsRequest.request:type_name -> ingester.v1.SelectProfilesRequest - 31, // 21: ingester.v1.MergeProfilesLabelsRequest.stack_trace_selector:type_name -> types.v1.StackTraceSelector + 34, // 21: ingester.v1.MergeProfilesLabelsRequest.stack_trace_selector:type_name -> types.v1.StackTraceSelector 15, // 22: ingester.v1.MergeProfilesLabelsResponse.selectedProfiles:type_name -> ingester.v1.ProfileSets - 32, // 23: ingester.v1.MergeProfilesLabelsResponse.series:type_name -> types.v1.Series + 35, // 23: ingester.v1.MergeProfilesLabelsResponse.series:type_name -> types.v1.Series 7, // 24: ingester.v1.MergeProfilesPprofRequest.request:type_name -> ingester.v1.SelectProfilesRequest - 31, // 25: ingester.v1.MergeProfilesPprofRequest.stack_trace_selector:type_name -> types.v1.StackTraceSelector + 34, // 25: ingester.v1.MergeProfilesPprofRequest.stack_trace_selector:type_name -> types.v1.StackTraceSelector 15, // 26: ingester.v1.MergeProfilesPprofResponse.selectedProfiles:type_name -> ingester.v1.ProfileSets - 33, // 27: ingester.v1.BlockMetadataResponse.blocks:type_name -> types.v1.BlockInfo + 36, // 27: ingester.v1.BlockMetadataResponse.blocks:type_name -> types.v1.BlockInfo 26, // 28: ingester.v1.Hints.block:type_name -> ingester.v1.BlockHints - 34, // 29: ingester.v1.IngesterService.Push:input_type -> push.v1.PushRequest - 35, // 30: ingester.v1.IngesterService.LabelValues:input_type -> types.v1.LabelValuesRequest - 36, // 31: ingester.v1.IngesterService.LabelNames:input_type -> types.v1.LabelNamesRequest - 1, // 32: ingester.v1.IngesterService.ProfileTypes:input_type -> ingester.v1.ProfileTypesRequest - 3, // 33: ingester.v1.IngesterService.Series:input_type -> ingester.v1.SeriesRequest - 5, // 34: ingester.v1.IngesterService.Flush:input_type -> ingester.v1.FlushRequest - 8, // 35: ingester.v1.IngesterService.MergeProfilesStacktraces:input_type -> ingester.v1.MergeProfilesStacktracesRequest - 19, // 36: ingester.v1.IngesterService.MergeProfilesLabels:input_type -> ingester.v1.MergeProfilesLabelsRequest - 21, // 37: ingester.v1.IngesterService.MergeProfilesPprof:input_type -> ingester.v1.MergeProfilesPprofRequest - 12, // 38: ingester.v1.IngesterService.MergeSpanProfile:input_type -> ingester.v1.MergeSpanProfileRequest - 23, // 39: ingester.v1.IngesterService.BlockMetadata:input_type -> ingester.v1.BlockMetadataRequest - 37, // 40: ingester.v1.IngesterService.GetProfileStats:input_type -> types.v1.GetProfileStatsRequest - 38, // 41: ingester.v1.IngesterService.Push:output_type -> push.v1.PushResponse - 39, // 42: ingester.v1.IngesterService.LabelValues:output_type -> types.v1.LabelValuesResponse - 40, // 43: ingester.v1.IngesterService.LabelNames:output_type -> types.v1.LabelNamesResponse - 2, // 44: ingester.v1.IngesterService.ProfileTypes:output_type -> ingester.v1.ProfileTypesResponse - 4, // 45: ingester.v1.IngesterService.Series:output_type -> ingester.v1.SeriesResponse - 6, // 46: ingester.v1.IngesterService.Flush:output_type -> ingester.v1.FlushResponse - 10, // 47: ingester.v1.IngesterService.MergeProfilesStacktraces:output_type -> ingester.v1.MergeProfilesStacktracesResponse - 20, // 48: ingester.v1.IngesterService.MergeProfilesLabels:output_type -> ingester.v1.MergeProfilesLabelsResponse - 22, // 49: ingester.v1.IngesterService.MergeProfilesPprof:output_type -> ingester.v1.MergeProfilesPprofResponse - 13, // 50: ingester.v1.IngesterService.MergeSpanProfile:output_type -> ingester.v1.MergeSpanProfileResponse - 24, // 51: ingester.v1.IngesterService.BlockMetadata:output_type -> ingester.v1.BlockMetadataResponse - 41, // 52: ingester.v1.IngesterService.GetProfileStats:output_type -> types.v1.GetProfileStatsResponse - 41, // [41:53] is the sub-list for method output_type - 29, // [29:41] is the sub-list for method input_type - 29, // [29:29] is the sub-list for extension type_name - 29, // [29:29] is the sub-list for extension extendee - 0, // [0:29] is the sub-list for field type_name + 29, // 29: ingester.v1.GetBlockStatsResponse.block_stats:type_name -> ingester.v1.BlockStats + 37, // 30: ingester.v1.IngesterService.Push:input_type -> push.v1.PushRequest + 38, // 31: ingester.v1.IngesterService.LabelValues:input_type -> types.v1.LabelValuesRequest + 39, // 32: ingester.v1.IngesterService.LabelNames:input_type -> types.v1.LabelNamesRequest + 1, // 33: ingester.v1.IngesterService.ProfileTypes:input_type -> ingester.v1.ProfileTypesRequest + 3, // 34: ingester.v1.IngesterService.Series:input_type -> ingester.v1.SeriesRequest + 5, // 35: ingester.v1.IngesterService.Flush:input_type -> ingester.v1.FlushRequest + 8, // 36: ingester.v1.IngesterService.MergeProfilesStacktraces:input_type -> ingester.v1.MergeProfilesStacktracesRequest + 19, // 37: ingester.v1.IngesterService.MergeProfilesLabels:input_type -> ingester.v1.MergeProfilesLabelsRequest + 21, // 38: ingester.v1.IngesterService.MergeProfilesPprof:input_type -> ingester.v1.MergeProfilesPprofRequest + 12, // 39: ingester.v1.IngesterService.MergeSpanProfile:input_type -> ingester.v1.MergeSpanProfileRequest + 23, // 40: ingester.v1.IngesterService.BlockMetadata:input_type -> ingester.v1.BlockMetadataRequest + 40, // 41: ingester.v1.IngesterService.GetProfileStats:input_type -> types.v1.GetProfileStatsRequest + 27, // 42: ingester.v1.IngesterService.GetBlockStats:input_type -> ingester.v1.GetBlockStatsRequest + 41, // 43: ingester.v1.IngesterService.Push:output_type -> push.v1.PushResponse + 42, // 44: ingester.v1.IngesterService.LabelValues:output_type -> types.v1.LabelValuesResponse + 43, // 45: ingester.v1.IngesterService.LabelNames:output_type -> types.v1.LabelNamesResponse + 2, // 46: ingester.v1.IngesterService.ProfileTypes:output_type -> ingester.v1.ProfileTypesResponse + 4, // 47: ingester.v1.IngesterService.Series:output_type -> ingester.v1.SeriesResponse + 6, // 48: ingester.v1.IngesterService.Flush:output_type -> ingester.v1.FlushResponse + 10, // 49: ingester.v1.IngesterService.MergeProfilesStacktraces:output_type -> ingester.v1.MergeProfilesStacktracesResponse + 20, // 50: ingester.v1.IngesterService.MergeProfilesLabels:output_type -> ingester.v1.MergeProfilesLabelsResponse + 22, // 51: ingester.v1.IngesterService.MergeProfilesPprof:output_type -> ingester.v1.MergeProfilesPprofResponse + 13, // 52: ingester.v1.IngesterService.MergeSpanProfile:output_type -> ingester.v1.MergeSpanProfileResponse + 24, // 53: ingester.v1.IngesterService.BlockMetadata:output_type -> ingester.v1.BlockMetadataResponse + 44, // 54: ingester.v1.IngesterService.GetProfileStats:output_type -> types.v1.GetProfileStatsResponse + 28, // 55: ingester.v1.IngesterService.GetBlockStats:output_type -> ingester.v1.GetBlockStatsResponse + 43, // [43:56] is the sub-list for method output_type + 30, // [30:43] is the sub-list for method input_type + 30, // [30:30] is the sub-list for extension type_name + 30, // [30:30] is the sub-list for extension extendee + 0, // [0:30] is the sub-list for field type_name } func init() { file_ingester_v1_ingester_proto_init() } @@ -2403,6 +2618,42 @@ func file_ingester_v1_ingester_proto_init() { return nil } } + file_ingester_v1_ingester_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetBlockStatsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ingester_v1_ingester_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetBlockStatsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ingester_v1_ingester_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BlockStats); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_ingester_v1_ingester_proto_msgTypes[6].OneofWrappers = []interface{}{} file_ingester_v1_ingester_proto_msgTypes[7].OneofWrappers = []interface{}{} @@ -2416,7 +2667,7 @@ func file_ingester_v1_ingester_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_ingester_v1_ingester_proto_rawDesc, NumEnums: 1, - NumMessages: 26, + NumMessages: 29, NumExtensions: 0, NumServices: 1, }, diff --git a/api/gen/proto/go/ingester/v1/ingester_vtproto.pb.go b/api/gen/proto/go/ingester/v1/ingester_vtproto.pb.go index e65538cb4a..286c2b25c9 100644 --- a/api/gen/proto/go/ingester/v1/ingester_vtproto.pb.go +++ b/api/gen/proto/go/ingester/v1/ingester_vtproto.pb.go @@ -700,6 +700,73 @@ func (m *BlockHints) CloneMessageVT() proto.Message { return m.CloneVT() } +func (m *GetBlockStatsRequest) CloneVT() *GetBlockStatsRequest { + if m == nil { + return (*GetBlockStatsRequest)(nil) + } + r := &GetBlockStatsRequest{} + if rhs := m.Ulids; rhs != nil { + tmpContainer := make([]string, len(rhs)) + copy(tmpContainer, rhs) + r.Ulids = tmpContainer + } + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *GetBlockStatsRequest) CloneMessageVT() proto.Message { + return m.CloneVT() +} + +func (m *GetBlockStatsResponse) CloneVT() *GetBlockStatsResponse { + if m == nil { + return (*GetBlockStatsResponse)(nil) + } + r := &GetBlockStatsResponse{} + if rhs := m.BlockStats; rhs != nil { + tmpContainer := make([]*BlockStats, len(rhs)) + for k, v := range rhs { + tmpContainer[k] = v.CloneVT() + } + r.BlockStats = tmpContainer + } + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *GetBlockStatsResponse) CloneMessageVT() proto.Message { + return m.CloneVT() +} + +func (m *BlockStats) CloneVT() *BlockStats { + if m == nil { + return (*BlockStats)(nil) + } + r := &BlockStats{ + SeriesCount: m.SeriesCount, + ProfileCount: m.ProfileCount, + SampleCount: m.SampleCount, + IndexBytes: m.IndexBytes, + ProfileBytes: m.ProfileBytes, + SymbolBytes: m.SymbolBytes, + } + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *BlockStats) CloneMessageVT() proto.Message { + return m.CloneVT() +} + func (this *ProfileTypesRequest) EqualVT(that *ProfileTypesRequest) bool { if this == that { return true @@ -1548,6 +1615,98 @@ func (this *BlockHints) EqualMessageVT(thatMsg proto.Message) bool { } return this.EqualVT(that) } +func (this *GetBlockStatsRequest) EqualVT(that *GetBlockStatsRequest) bool { + if this == that { + return true + } else if this == nil || that == nil { + return false + } + if len(this.Ulids) != len(that.Ulids) { + return false + } + for i, vx := range this.Ulids { + vy := that.Ulids[i] + if vx != vy { + return false + } + } + return string(this.unknownFields) == string(that.unknownFields) +} + +func (this *GetBlockStatsRequest) EqualMessageVT(thatMsg proto.Message) bool { + that, ok := thatMsg.(*GetBlockStatsRequest) + if !ok { + return false + } + return this.EqualVT(that) +} +func (this *GetBlockStatsResponse) EqualVT(that *GetBlockStatsResponse) bool { + if this == that { + return true + } else if this == nil || that == nil { + return false + } + if len(this.BlockStats) != len(that.BlockStats) { + return false + } + for i, vx := range this.BlockStats { + vy := that.BlockStats[i] + if p, q := vx, vy; p != q { + if p == nil { + p = &BlockStats{} + } + if q == nil { + q = &BlockStats{} + } + if !p.EqualVT(q) { + return false + } + } + } + return string(this.unknownFields) == string(that.unknownFields) +} + +func (this *GetBlockStatsResponse) EqualMessageVT(thatMsg proto.Message) bool { + that, ok := thatMsg.(*GetBlockStatsResponse) + if !ok { + return false + } + return this.EqualVT(that) +} +func (this *BlockStats) EqualVT(that *BlockStats) bool { + if this == that { + return true + } else if this == nil || that == nil { + return false + } + if this.SeriesCount != that.SeriesCount { + return false + } + if this.ProfileCount != that.ProfileCount { + return false + } + if this.SampleCount != that.SampleCount { + return false + } + if this.IndexBytes != that.IndexBytes { + return false + } + if this.ProfileBytes != that.ProfileBytes { + return false + } + if this.SymbolBytes != that.SymbolBytes { + return false + } + return string(this.unknownFields) == string(that.unknownFields) +} + +func (this *BlockStats) EqualMessageVT(thatMsg proto.Message) bool { + that, ok := thatMsg.(*BlockStats) + if !ok { + return false + } + return this.EqualVT(that) +} // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. @@ -1573,6 +1732,7 @@ type IngesterServiceClient interface { BlockMetadata(ctx context.Context, in *BlockMetadataRequest, opts ...grpc.CallOption) (*BlockMetadataResponse, error) // GetProfileStats returns profile stats for the current tenant. GetProfileStats(ctx context.Context, in *v1.GetProfileStatsRequest, opts ...grpc.CallOption) (*v1.GetProfileStatsResponse, error) + GetBlockStats(ctx context.Context, in *GetBlockStatsRequest, opts ...grpc.CallOption) (*GetBlockStatsResponse, error) } type ingesterServiceClient struct { @@ -1779,6 +1939,15 @@ func (c *ingesterServiceClient) GetProfileStats(ctx context.Context, in *v1.GetP return out, nil } +func (c *ingesterServiceClient) GetBlockStats(ctx context.Context, in *GetBlockStatsRequest, opts ...grpc.CallOption) (*GetBlockStatsResponse, error) { + out := new(GetBlockStatsResponse) + err := c.cc.Invoke(ctx, "/ingester.v1.IngesterService/GetBlockStats", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // IngesterServiceServer is the server API for IngesterService service. // All implementations must embed UnimplementedIngesterServiceServer // for forward compatibility @@ -1798,6 +1967,7 @@ type IngesterServiceServer interface { BlockMetadata(context.Context, *BlockMetadataRequest) (*BlockMetadataResponse, error) // GetProfileStats returns profile stats for the current tenant. GetProfileStats(context.Context, *v1.GetProfileStatsRequest) (*v1.GetProfileStatsResponse, error) + GetBlockStats(context.Context, *GetBlockStatsRequest) (*GetBlockStatsResponse, error) mustEmbedUnimplementedIngesterServiceServer() } @@ -1841,6 +2011,9 @@ func (UnimplementedIngesterServiceServer) BlockMetadata(context.Context, *BlockM func (UnimplementedIngesterServiceServer) GetProfileStats(context.Context, *v1.GetProfileStatsRequest) (*v1.GetProfileStatsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetProfileStats not implemented") } +func (UnimplementedIngesterServiceServer) GetBlockStats(context.Context, *GetBlockStatsRequest) (*GetBlockStatsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetBlockStats not implemented") +} func (UnimplementedIngesterServiceServer) mustEmbedUnimplementedIngesterServiceServer() {} // UnsafeIngesterServiceServer may be embedded to opt out of forward compatibility for this service. @@ -2102,6 +2275,24 @@ func _IngesterService_GetProfileStats_Handler(srv interface{}, ctx context.Conte return interceptor(ctx, in, info, handler) } +func _IngesterService_GetBlockStats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetBlockStatsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(IngesterServiceServer).GetBlockStats(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ingester.v1.IngesterService/GetBlockStats", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(IngesterServiceServer).GetBlockStats(ctx, req.(*GetBlockStatsRequest)) + } + return interceptor(ctx, in, info, handler) +} + // IngesterService_ServiceDesc is the grpc.ServiceDesc for IngesterService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -2141,6 +2332,10 @@ var IngesterService_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetProfileStats", Handler: _IngesterService_GetProfileStats_Handler, }, + { + MethodName: "GetBlockStats", + Handler: _IngesterService_GetBlockStats_Handler, + }, }, Streams: []grpc.StreamDesc{ { @@ -3723,93 +3918,243 @@ func (m *BlockHints) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func encodeVarint(dAtA []byte, offset int, v uint64) int { - offset -= sov(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ +func (m *GetBlockStatsRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil } - dAtA[offset] = uint8(v) - return base + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil } -func (m *ProfileTypesRequest) SizeVT() (n int) { + +func (m *GetBlockStatsRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *GetBlockStatsRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if m == nil { - return 0 + return 0, nil } + i := len(dAtA) + _ = i var l int _ = l - if m.Start != 0 { - n += 1 + sov(uint64(m.Start)) + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) } - if m.End != 0 { - n += 1 + sov(uint64(m.End)) + if len(m.Ulids) > 0 { + for iNdEx := len(m.Ulids) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Ulids[iNdEx]) + copy(dAtA[i:], m.Ulids[iNdEx]) + i = encodeVarint(dAtA, i, uint64(len(m.Ulids[iNdEx]))) + i-- + dAtA[i] = 0xa + } } - n += len(m.unknownFields) - return n + return len(dAtA) - i, nil } -func (m *ProfileTypesResponse) SizeVT() (n int) { +func (m *GetBlockStatsResponse) MarshalVT() (dAtA []byte, err error) { if m == nil { - return 0 + return nil, nil } - var l int - _ = l - if len(m.ProfileTypes) > 0 { - for _, e := range m.ProfileTypes { - if size, ok := interface{}(e).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(e) - } - n += 1 + l + sov(uint64(l)) - } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err } - n += len(m.unknownFields) - return n + return dAtA[:n], nil } -func (m *SeriesRequest) SizeVT() (n int) { +func (m *GetBlockStatsResponse) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *GetBlockStatsResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if m == nil { - return 0 + return 0, nil } + i := len(dAtA) + _ = i var l int _ = l - if len(m.Matchers) > 0 { - for _, s := range m.Matchers { - l = len(s) - n += 1 + l + sov(uint64(l)) - } + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) } - if len(m.LabelNames) > 0 { - for _, s := range m.LabelNames { - l = len(s) - n += 1 + l + sov(uint64(l)) + if len(m.BlockStats) > 0 { + for iNdEx := len(m.BlockStats) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.BlockStats[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0xa } } - if m.Start != 0 { - n += 1 + sov(uint64(m.Start)) - } - if m.End != 0 { - n += 1 + sov(uint64(m.End)) - } - n += len(m.unknownFields) - return n + return len(dAtA) - i, nil } -func (m *SeriesResponse) SizeVT() (n int) { +func (m *BlockStats) MarshalVT() (dAtA []byte, err error) { if m == nil { - return 0 + return nil, nil } - var l int - _ = l - if len(m.LabelsSet) > 0 { - for _, e := range m.LabelsSet { - if size, ok := interface{}(e).(interface { - SizeVT() int + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *BlockStats) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *BlockStats) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.SymbolBytes != 0 { + i = encodeVarint(dAtA, i, uint64(m.SymbolBytes)) + i-- + dAtA[i] = 0x38 + } + if m.ProfileBytes != 0 { + i = encodeVarint(dAtA, i, uint64(m.ProfileBytes)) + i-- + dAtA[i] = 0x30 + } + if m.IndexBytes != 0 { + i = encodeVarint(dAtA, i, uint64(m.IndexBytes)) + i-- + dAtA[i] = 0x28 + } + if m.SampleCount != 0 { + i = encodeVarint(dAtA, i, uint64(m.SampleCount)) + i-- + dAtA[i] = 0x20 + } + if m.ProfileCount != 0 { + i = encodeVarint(dAtA, i, uint64(m.ProfileCount)) + i-- + dAtA[i] = 0x18 + } + if m.SeriesCount != 0 { + i = encodeVarint(dAtA, i, uint64(m.SeriesCount)) + i-- + dAtA[i] = 0x10 + } + return len(dAtA) - i, nil +} + +func encodeVarint(dAtA []byte, offset int, v uint64) int { + offset -= sov(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *ProfileTypesRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Start != 0 { + n += 1 + sov(uint64(m.Start)) + } + if m.End != 0 { + n += 1 + sov(uint64(m.End)) + } + n += len(m.unknownFields) + return n +} + +func (m *ProfileTypesResponse) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.ProfileTypes) > 0 { + for _, e := range m.ProfileTypes { + if size, ok := interface{}(e).(interface { + SizeVT() int + }); ok { + l = size.SizeVT() + } else { + l = proto.Size(e) + } + n += 1 + l + sov(uint64(l)) + } + } + n += len(m.unknownFields) + return n +} + +func (m *SeriesRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Matchers) > 0 { + for _, s := range m.Matchers { + l = len(s) + n += 1 + l + sov(uint64(l)) + } + } + if len(m.LabelNames) > 0 { + for _, s := range m.LabelNames { + l = len(s) + n += 1 + l + sov(uint64(l)) + } + } + if m.Start != 0 { + n += 1 + sov(uint64(m.Start)) + } + if m.End != 0 { + n += 1 + sov(uint64(m.End)) + } + n += len(m.unknownFields) + return n +} + +func (m *SeriesResponse) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.LabelsSet) > 0 { + for _, e := range m.LabelsSet { + if size, ok := interface{}(e).(interface { + SizeVT() int }); ok { l = size.SizeVT() } else { @@ -4325,6 +4670,66 @@ func (m *BlockHints) SizeVT() (n int) { return n } +func (m *GetBlockStatsRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Ulids) > 0 { + for _, s := range m.Ulids { + l = len(s) + n += 1 + l + sov(uint64(l)) + } + } + n += len(m.unknownFields) + return n +} + +func (m *GetBlockStatsResponse) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.BlockStats) > 0 { + for _, e := range m.BlockStats { + l = e.SizeVT() + n += 1 + l + sov(uint64(l)) + } + } + n += len(m.unknownFields) + return n +} + +func (m *BlockStats) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SeriesCount != 0 { + n += 1 + sov(uint64(m.SeriesCount)) + } + if m.ProfileCount != 0 { + n += 1 + sov(uint64(m.ProfileCount)) + } + if m.SampleCount != 0 { + n += 1 + sov(uint64(m.SampleCount)) + } + if m.IndexBytes != 0 { + n += 1 + sov(uint64(m.IndexBytes)) + } + if m.ProfileBytes != 0 { + n += 1 + sov(uint64(m.ProfileBytes)) + } + if m.SymbolBytes != 0 { + n += 1 + sov(uint64(m.SymbolBytes)) + } + n += len(m.unknownFields) + return n +} + func sov(x uint64) (n int) { return (bits.Len64(x|1) + 6) / 7 } @@ -7830,6 +8235,339 @@ func (m *BlockHints) UnmarshalVT(dAtA []byte) error { } return nil } +func (m *GetBlockStatsRequest) UnmarshalVT(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 ErrIntOverflow + } + 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: GetBlockStatsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetBlockStatsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ulids", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Ulids = append(m.Ulids, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetBlockStatsResponse) UnmarshalVT(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 ErrIntOverflow + } + 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: GetBlockStatsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetBlockStatsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockStats", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BlockStats = append(m.BlockStats, &BlockStats{}) + if err := m.BlockStats[len(m.BlockStats)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *BlockStats) UnmarshalVT(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 ErrIntOverflow + } + 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: BlockStats: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: BlockStats: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SeriesCount", wireType) + } + m.SeriesCount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SeriesCount |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ProfileCount", wireType) + } + m.ProfileCount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ProfileCount |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SampleCount", wireType) + } + m.SampleCount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SampleCount |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IndexBytes", wireType) + } + m.IndexBytes = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.IndexBytes |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ProfileBytes", wireType) + } + m.ProfileBytes = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ProfileBytes |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SymbolBytes", wireType) + } + m.SymbolBytes = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SymbolBytes |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skip(dAtA []byte) (n int, err error) { l := len(dAtA) diff --git a/api/gen/proto/go/ingester/v1/ingesterv1connect/ingester.connect.go b/api/gen/proto/go/ingester/v1/ingesterv1connect/ingester.connect.go index 0540374078..9f629348a5 100644 --- a/api/gen/proto/go/ingester/v1/ingesterv1connect/ingester.connect.go +++ b/api/gen/proto/go/ingester/v1/ingesterv1connect/ingester.connect.go @@ -68,6 +68,9 @@ const ( // IngesterServiceGetProfileStatsProcedure is the fully-qualified name of the IngesterService's // GetProfileStats RPC. IngesterServiceGetProfileStatsProcedure = "/ingester.v1.IngesterService/GetProfileStats" + // IngesterServiceGetBlockStatsProcedure is the fully-qualified name of the IngesterService's + // GetBlockStats RPC. + IngesterServiceGetBlockStatsProcedure = "/ingester.v1.IngesterService/GetBlockStats" ) // These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. @@ -85,6 +88,7 @@ var ( ingesterServiceMergeSpanProfileMethodDescriptor = ingesterServiceServiceDescriptor.Methods().ByName("MergeSpanProfile") ingesterServiceBlockMetadataMethodDescriptor = ingesterServiceServiceDescriptor.Methods().ByName("BlockMetadata") ingesterServiceGetProfileStatsMethodDescriptor = ingesterServiceServiceDescriptor.Methods().ByName("GetProfileStats") + ingesterServiceGetBlockStatsMethodDescriptor = ingesterServiceServiceDescriptor.Methods().ByName("GetBlockStats") ) // IngesterServiceClient is a client for the ingester.v1.IngesterService service. @@ -104,6 +108,7 @@ type IngesterServiceClient interface { BlockMetadata(context.Context, *connect.Request[v1.BlockMetadataRequest]) (*connect.Response[v1.BlockMetadataResponse], error) // GetProfileStats returns profile stats for the current tenant. GetProfileStats(context.Context, *connect.Request[v12.GetProfileStatsRequest]) (*connect.Response[v12.GetProfileStatsResponse], error) + GetBlockStats(context.Context, *connect.Request[v1.GetBlockStatsRequest]) (*connect.Response[v1.GetBlockStatsResponse], error) } // NewIngesterServiceClient constructs a client for the ingester.v1.IngesterService service. By @@ -188,6 +193,12 @@ func NewIngesterServiceClient(httpClient connect.HTTPClient, baseURL string, opt connect.WithSchema(ingesterServiceGetProfileStatsMethodDescriptor), connect.WithClientOptions(opts...), ), + getBlockStats: connect.NewClient[v1.GetBlockStatsRequest, v1.GetBlockStatsResponse]( + httpClient, + baseURL+IngesterServiceGetBlockStatsProcedure, + connect.WithSchema(ingesterServiceGetBlockStatsMethodDescriptor), + connect.WithClientOptions(opts...), + ), } } @@ -205,6 +216,7 @@ type ingesterServiceClient struct { mergeSpanProfile *connect.Client[v1.MergeSpanProfileRequest, v1.MergeSpanProfileResponse] blockMetadata *connect.Client[v1.BlockMetadataRequest, v1.BlockMetadataResponse] getProfileStats *connect.Client[v12.GetProfileStatsRequest, v12.GetProfileStatsResponse] + getBlockStats *connect.Client[v1.GetBlockStatsRequest, v1.GetBlockStatsResponse] } // Push calls ingester.v1.IngesterService.Push. @@ -267,6 +279,11 @@ func (c *ingesterServiceClient) GetProfileStats(ctx context.Context, req *connec return c.getProfileStats.CallUnary(ctx, req) } +// GetBlockStats calls ingester.v1.IngesterService.GetBlockStats. +func (c *ingesterServiceClient) GetBlockStats(ctx context.Context, req *connect.Request[v1.GetBlockStatsRequest]) (*connect.Response[v1.GetBlockStatsResponse], error) { + return c.getBlockStats.CallUnary(ctx, req) +} + // IngesterServiceHandler is an implementation of the ingester.v1.IngesterService service. type IngesterServiceHandler interface { Push(context.Context, *connect.Request[v11.PushRequest]) (*connect.Response[v11.PushResponse], error) @@ -284,6 +301,7 @@ type IngesterServiceHandler interface { BlockMetadata(context.Context, *connect.Request[v1.BlockMetadataRequest]) (*connect.Response[v1.BlockMetadataResponse], error) // GetProfileStats returns profile stats for the current tenant. GetProfileStats(context.Context, *connect.Request[v12.GetProfileStatsRequest]) (*connect.Response[v12.GetProfileStatsResponse], error) + GetBlockStats(context.Context, *connect.Request[v1.GetBlockStatsRequest]) (*connect.Response[v1.GetBlockStatsResponse], error) } // NewIngesterServiceHandler builds an HTTP handler from the service implementation. It returns the @@ -364,6 +382,12 @@ func NewIngesterServiceHandler(svc IngesterServiceHandler, opts ...connect.Handl connect.WithSchema(ingesterServiceGetProfileStatsMethodDescriptor), connect.WithHandlerOptions(opts...), ) + ingesterServiceGetBlockStatsHandler := connect.NewUnaryHandler( + IngesterServiceGetBlockStatsProcedure, + svc.GetBlockStats, + connect.WithSchema(ingesterServiceGetBlockStatsMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) return "/ingester.v1.IngesterService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { case IngesterServicePushProcedure: @@ -390,6 +414,8 @@ func NewIngesterServiceHandler(svc IngesterServiceHandler, opts ...connect.Handl ingesterServiceBlockMetadataHandler.ServeHTTP(w, r) case IngesterServiceGetProfileStatsProcedure: ingesterServiceGetProfileStatsHandler.ServeHTTP(w, r) + case IngesterServiceGetBlockStatsProcedure: + ingesterServiceGetBlockStatsHandler.ServeHTTP(w, r) default: http.NotFound(w, r) } @@ -446,3 +472,7 @@ func (UnimplementedIngesterServiceHandler) BlockMetadata(context.Context, *conne func (UnimplementedIngesterServiceHandler) GetProfileStats(context.Context, *connect.Request[v12.GetProfileStatsRequest]) (*connect.Response[v12.GetProfileStatsResponse], error) { return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ingester.v1.IngesterService.GetProfileStats is not implemented")) } + +func (UnimplementedIngesterServiceHandler) GetBlockStats(context.Context, *connect.Request[v1.GetBlockStatsRequest]) (*connect.Response[v1.GetBlockStatsResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ingester.v1.IngesterService.GetBlockStats is not implemented")) +} diff --git a/api/gen/proto/go/ingester/v1/ingesterv1connect/ingester.connect.mux.go b/api/gen/proto/go/ingester/v1/ingesterv1connect/ingester.connect.mux.go index 96ac649a6f..a1c59579ff 100644 --- a/api/gen/proto/go/ingester/v1/ingesterv1connect/ingester.connect.mux.go +++ b/api/gen/proto/go/ingester/v1/ingesterv1connect/ingester.connect.mux.go @@ -79,4 +79,9 @@ func RegisterIngesterServiceHandler(mux *mux.Router, svc IngesterServiceHandler, svc.GetProfileStats, opts..., )) + mux.Handle("/ingester.v1.IngesterService/GetBlockStats", connect.NewUnaryHandler( + "/ingester.v1.IngesterService/GetBlockStats", + svc.GetBlockStats, + opts..., + )) } diff --git a/api/gen/proto/go/querier/v1/querier.pb.go b/api/gen/proto/go/querier/v1/querier.pb.go index df58bc561c..e9475ba0de 100644 --- a/api/gen/proto/go/querier/v1/querier.pb.go +++ b/api/gen/proto/go/querier/v1/querier.pb.go @@ -1068,6 +1068,298 @@ func (x *SelectSeriesResponse) GetSeries() []*v1.Series { return nil } +type AnalyzeQueryRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Start int64 `protobuf:"varint,2,opt,name=start,proto3" json:"start,omitempty"` + End int64 `protobuf:"varint,3,opt,name=end,proto3" json:"end,omitempty"` + Query string `protobuf:"bytes,4,opt,name=query,proto3" json:"query,omitempty"` +} + +func (x *AnalyzeQueryRequest) Reset() { + *x = AnalyzeQueryRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_querier_v1_querier_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AnalyzeQueryRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AnalyzeQueryRequest) ProtoMessage() {} + +func (x *AnalyzeQueryRequest) ProtoReflect() protoreflect.Message { + mi := &file_querier_v1_querier_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AnalyzeQueryRequest.ProtoReflect.Descriptor instead. +func (*AnalyzeQueryRequest) Descriptor() ([]byte, []int) { + return file_querier_v1_querier_proto_rawDescGZIP(), []int{16} +} + +func (x *AnalyzeQueryRequest) GetStart() int64 { + if x != nil { + return x.Start + } + return 0 +} + +func (x *AnalyzeQueryRequest) GetEnd() int64 { + if x != nil { + return x.End + } + return 0 +} + +func (x *AnalyzeQueryRequest) GetQuery() string { + if x != nil { + return x.Query + } + return "" +} + +type AnalyzeQueryResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + QueryScopes []*QueryScope `protobuf:"bytes,1,rep,name=query_scopes,json=queryScopes,proto3" json:"query_scopes,omitempty"` // detailed view of what the query will require + QueryImpact *QueryImpact `protobuf:"bytes,2,opt,name=query_impact,json=queryImpact,proto3" json:"query_impact,omitempty"` // summary of the query impact / performance +} + +func (x *AnalyzeQueryResponse) Reset() { + *x = AnalyzeQueryResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_querier_v1_querier_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AnalyzeQueryResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AnalyzeQueryResponse) ProtoMessage() {} + +func (x *AnalyzeQueryResponse) ProtoReflect() protoreflect.Message { + mi := &file_querier_v1_querier_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AnalyzeQueryResponse.ProtoReflect.Descriptor instead. +func (*AnalyzeQueryResponse) Descriptor() ([]byte, []int) { + return file_querier_v1_querier_proto_rawDescGZIP(), []int{17} +} + +func (x *AnalyzeQueryResponse) GetQueryScopes() []*QueryScope { + if x != nil { + return x.QueryScopes + } + return nil +} + +func (x *AnalyzeQueryResponse) GetQueryImpact() *QueryImpact { + if x != nil { + return x.QueryImpact + } + return nil +} + +type QueryScope struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ComponentType string `protobuf:"bytes,1,opt,name=component_type,json=componentType,proto3" json:"component_type,omitempty"` // a descriptive high level name of the component processing one part of the query (e.g., "short term storage") + ComponentCount uint64 `protobuf:"varint,2,opt,name=component_count,json=componentCount,proto3" json:"component_count,omitempty"` // how many components of this type will process the query (indicator of read-path replication) + BlockCount uint64 `protobuf:"varint,3,opt,name=block_count,json=blockCount,proto3" json:"block_count,omitempty"` + SeriesCount uint64 `protobuf:"varint,4,opt,name=series_count,json=seriesCount,proto3" json:"series_count,omitempty"` + ProfileCount uint64 `protobuf:"varint,5,opt,name=profile_count,json=profileCount,proto3" json:"profile_count,omitempty"` + SampleCount uint64 `protobuf:"varint,6,opt,name=sample_count,json=sampleCount,proto3" json:"sample_count,omitempty"` + IndexBytes uint64 `protobuf:"varint,7,opt,name=index_bytes,json=indexBytes,proto3" json:"index_bytes,omitempty"` + ProfileBytes uint64 `protobuf:"varint,8,opt,name=profile_bytes,json=profileBytes,proto3" json:"profile_bytes,omitempty"` + SymbolBytes uint64 `protobuf:"varint,9,opt,name=symbol_bytes,json=symbolBytes,proto3" json:"symbol_bytes,omitempty"` +} + +func (x *QueryScope) Reset() { + *x = QueryScope{} + if protoimpl.UnsafeEnabled { + mi := &file_querier_v1_querier_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryScope) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryScope) ProtoMessage() {} + +func (x *QueryScope) ProtoReflect() protoreflect.Message { + mi := &file_querier_v1_querier_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QueryScope.ProtoReflect.Descriptor instead. +func (*QueryScope) Descriptor() ([]byte, []int) { + return file_querier_v1_querier_proto_rawDescGZIP(), []int{18} +} + +func (x *QueryScope) GetComponentType() string { + if x != nil { + return x.ComponentType + } + return "" +} + +func (x *QueryScope) GetComponentCount() uint64 { + if x != nil { + return x.ComponentCount + } + return 0 +} + +func (x *QueryScope) GetBlockCount() uint64 { + if x != nil { + return x.BlockCount + } + return 0 +} + +func (x *QueryScope) GetSeriesCount() uint64 { + if x != nil { + return x.SeriesCount + } + return 0 +} + +func (x *QueryScope) GetProfileCount() uint64 { + if x != nil { + return x.ProfileCount + } + return 0 +} + +func (x *QueryScope) GetSampleCount() uint64 { + if x != nil { + return x.SampleCount + } + return 0 +} + +func (x *QueryScope) GetIndexBytes() uint64 { + if x != nil { + return x.IndexBytes + } + return 0 +} + +func (x *QueryScope) GetProfileBytes() uint64 { + if x != nil { + return x.ProfileBytes + } + return 0 +} + +func (x *QueryScope) GetSymbolBytes() uint64 { + if x != nil { + return x.SymbolBytes + } + return 0 +} + +type QueryImpact struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TotalBytesInTimeRange uint64 `protobuf:"varint,2,opt,name=total_bytes_in_time_range,json=totalBytesInTimeRange,proto3" json:"total_bytes_in_time_range,omitempty"` + TotalQueriedSeries uint64 `protobuf:"varint,3,opt,name=total_queried_series,json=totalQueriedSeries,proto3" json:"total_queried_series,omitempty"` + DeduplicationNeeded bool `protobuf:"varint,4,opt,name=deduplication_needed,json=deduplicationNeeded,proto3" json:"deduplication_needed,omitempty"` +} + +func (x *QueryImpact) Reset() { + *x = QueryImpact{} + if protoimpl.UnsafeEnabled { + mi := &file_querier_v1_querier_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryImpact) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryImpact) ProtoMessage() {} + +func (x *QueryImpact) ProtoReflect() protoreflect.Message { + mi := &file_querier_v1_querier_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QueryImpact.ProtoReflect.Descriptor instead. +func (*QueryImpact) Descriptor() ([]byte, []int) { + return file_querier_v1_querier_proto_rawDescGZIP(), []int{19} +} + +func (x *QueryImpact) GetTotalBytesInTimeRange() uint64 { + if x != nil { + return x.TotalBytesInTimeRange + } + return 0 +} + +func (x *QueryImpact) GetTotalQueriedSeries() uint64 { + if x != nil { + return x.TotalQueriedSeries + } + return 0 +} + +func (x *QueryImpact) GetDeduplicationNeeded() bool { + if x != nil { + return x.DeduplicationNeeded + } + return false +} + var File_querier_v1_querier_proto protoreflect.FileDescriptor var file_querier_v1_querier_proto_rawDesc = []byte{ @@ -1219,73 +1511,125 @@ var file_querier_v1_querier_proto_rawDesc = []byte{ 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x06, 0x73, - 0x65, 0x72, 0x69, 0x65, 0x73, 0x32, 0xe6, 0x06, 0x0a, 0x0e, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, - 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x53, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x66, - 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x1f, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x69, - 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x71, 0x75, 0x65, 0x72, - 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x54, 0x79, - 0x70, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, - 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x1c, 0x2e, 0x74, - 0x79, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x49, 0x0a, 0x0a, 0x4c, - 0x61, 0x62, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x1b, 0x2e, 0x74, 0x79, 0x70, 0x65, - 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x76, - 0x31, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x06, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, - 0x12, 0x19, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, - 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x71, 0x75, - 0x65, 0x72, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x71, 0x0a, 0x16, 0x53, 0x65, 0x6c, - 0x65, 0x63, 0x74, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x74, 0x72, 0x61, - 0x63, 0x65, 0x73, 0x12, 0x29, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x53, 0x74, 0x61, 0x63, - 0x6b, 0x74, 0x72, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, - 0x2e, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6c, 0x65, - 0x63, 0x74, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x74, 0x72, 0x61, 0x63, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x71, 0x0a, 0x16, - 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x50, - 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x29, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, + 0x65, 0x72, 0x69, 0x65, 0x73, 0x22, 0x53, 0x0a, 0x13, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x03, 0x65, 0x6e, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x8d, 0x01, 0x0a, 0x14, 0x41, + 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x0c, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x63, 0x6f, + 0x70, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x71, 0x75, 0x65, 0x72, + 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x63, 0x6f, 0x70, + 0x65, 0x52, 0x0b, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x3a, + 0x0a, 0x0c, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x69, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x49, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x52, 0x0b, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x49, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x22, 0xd1, 0x02, 0x0a, 0x0a, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, + 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6f, + 0x6e, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, + 0x72, 0x69, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x0b, 0x73, 0x65, 0x72, 0x69, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x23, 0x0a, + 0x0d, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x62, + 0x79, 0x74, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, + 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x70, + 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, + 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x0b, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0xac, + 0x01, 0x0a, 0x0b, 0x51, 0x75, 0x65, 0x72, 0x79, 0x49, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x12, 0x38, + 0x0a, 0x19, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x69, 0x6e, + 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x15, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x49, 0x6e, 0x54, + 0x69, 0x6d, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x74, 0x6f, 0x74, 0x61, + 0x6c, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x69, 0x65, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x51, 0x75, 0x65, + 0x72, 0x69, 0x65, 0x64, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, 0x31, 0x0a, 0x14, 0x64, 0x65, + 0x64, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x65, 0x65, 0x64, + 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x64, 0x65, 0x64, 0x75, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x65, 0x65, 0x64, 0x65, 0x64, 0x32, 0xbb, 0x07, + 0x0a, 0x0e, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x53, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, + 0x12, 0x1f, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, + 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x20, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, + 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x73, 0x12, 0x1c, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, + 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x61, + 0x62, 0x65, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x49, 0x0a, 0x0a, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, + 0x73, 0x12, 0x1b, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x61, 0x62, + 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x4e, + 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x41, + 0x0a, 0x06, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, 0x19, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x69, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x2e, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x71, 0x0a, 0x16, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x72, 0x67, 0x65, + 0x53, 0x74, 0x61, 0x63, 0x6b, 0x74, 0x72, 0x61, 0x63, 0x65, 0x73, 0x12, 0x29, 0x2e, 0x71, 0x75, + 0x65, 0x72, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x4d, + 0x65, 0x72, 0x67, 0x65, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x74, 0x72, 0x61, 0x63, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x53, - 0x70, 0x61, 0x6e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, - 0x65, 0x6c, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x50, 0x72, - 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x51, 0x0a, 0x12, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x50, 0x72, - 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x25, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, 0x2e, - 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x50, 0x72, - 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, - 0x22, 0x00, 0x12, 0x53, 0x0a, 0x0c, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x69, - 0x65, 0x73, 0x12, 0x1f, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, - 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x04, 0x44, 0x69, 0x66, 0x66, 0x12, - 0x17, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x66, - 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x69, - 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, - 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x20, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x74, 0x61, - 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x74, 0x79, 0x70, 0x65, - 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, - 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xab, - 0x01, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x42, 0x0c, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, - 0x01, 0x5a, 0x42, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, - 0x61, 0x66, 0x61, 0x6e, 0x61, 0x2f, 0x70, 0x79, 0x72, 0x6f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, - 0x2f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x71, 0x75, 0x65, 0x72, - 0x69, 0x65, 0x72, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x51, 0x58, 0x58, 0xaa, 0x02, 0x0a, 0x51, 0x75, - 0x65, 0x72, 0x69, 0x65, 0x72, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0a, 0x51, 0x75, 0x65, 0x72, 0x69, - 0x65, 0x72, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x16, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, 0x5c, - 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, - 0x0b, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x61, 0x63, 0x6b, 0x74, 0x72, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x71, 0x0a, 0x16, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x4d, 0x65, + 0x72, 0x67, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x29, + 0x2e, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x50, 0x72, 0x6f, 0x66, 0x69, + 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x71, 0x75, 0x65, 0x72, + 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x72, + 0x67, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x12, 0x53, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x25, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x22, 0x00, 0x12, 0x53, 0x0a, 0x0c, 0x53, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, 0x1f, 0x2e, 0x71, 0x75, 0x65, + 0x72, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x53, 0x65, + 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x71, 0x75, + 0x65, 0x72, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x53, + 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x3b, 0x0a, 0x04, 0x44, 0x69, 0x66, 0x66, 0x12, 0x17, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x18, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, + 0x66, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x0f, + 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, + 0x20, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, + 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x21, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x53, 0x0a, 0x0c, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, + 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x1f, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xab, 0x01, 0x0a, 0x0e, + 0x63, 0x6f, 0x6d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x42, 0x0c, + 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x42, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x66, 0x61, + 0x6e, 0x61, 0x2f, 0x70, 0x79, 0x72, 0x6f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x71, 0x75, + 0x65, 0x72, 0x69, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, + 0x76, 0x31, 0xa2, 0x02, 0x03, 0x51, 0x58, 0x58, 0xaa, 0x02, 0x0a, 0x51, 0x75, 0x65, 0x72, 0x69, + 0x65, 0x72, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0a, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, 0x5c, + 0x56, 0x31, 0xe2, 0x02, 0x16, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x72, 0x5c, 0x56, 0x31, 0x5c, + 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0b, 0x51, 0x75, + 0x65, 0x72, 0x69, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -1300,7 +1644,7 @@ func file_querier_v1_querier_proto_rawDescGZIP() []byte { return file_querier_v1_querier_proto_rawDescData } -var file_querier_v1_querier_proto_msgTypes = make([]protoimpl.MessageInfo, 16) +var file_querier_v1_querier_proto_msgTypes = make([]protoimpl.MessageInfo, 20) var file_querier_v1_querier_proto_goTypes = []interface{}{ (*ProfileTypesRequest)(nil), // 0: querier.v1.ProfileTypesRequest (*ProfileTypesResponse)(nil), // 1: querier.v1.ProfileTypesResponse @@ -1318,22 +1662,26 @@ var file_querier_v1_querier_proto_goTypes = []interface{}{ (*SelectMergeProfileRequest)(nil), // 13: querier.v1.SelectMergeProfileRequest (*SelectSeriesRequest)(nil), // 14: querier.v1.SelectSeriesRequest (*SelectSeriesResponse)(nil), // 15: querier.v1.SelectSeriesResponse - (*v1.ProfileType)(nil), // 16: types.v1.ProfileType - (*v1.Labels)(nil), // 17: types.v1.Labels - (*v1.StackTraceSelector)(nil), // 18: types.v1.StackTraceSelector - (v1.TimeSeriesAggregationType)(0), // 19: types.v1.TimeSeriesAggregationType - (*v1.Series)(nil), // 20: types.v1.Series - (*v1.LabelValuesRequest)(nil), // 21: types.v1.LabelValuesRequest - (*v1.LabelNamesRequest)(nil), // 22: types.v1.LabelNamesRequest - (*v1.GetProfileStatsRequest)(nil), // 23: types.v1.GetProfileStatsRequest - (*v1.LabelValuesResponse)(nil), // 24: types.v1.LabelValuesResponse - (*v1.LabelNamesResponse)(nil), // 25: types.v1.LabelNamesResponse - (*v11.Profile)(nil), // 26: google.v1.Profile - (*v1.GetProfileStatsResponse)(nil), // 27: types.v1.GetProfileStatsResponse + (*AnalyzeQueryRequest)(nil), // 16: querier.v1.AnalyzeQueryRequest + (*AnalyzeQueryResponse)(nil), // 17: querier.v1.AnalyzeQueryResponse + (*QueryScope)(nil), // 18: querier.v1.QueryScope + (*QueryImpact)(nil), // 19: querier.v1.QueryImpact + (*v1.ProfileType)(nil), // 20: types.v1.ProfileType + (*v1.Labels)(nil), // 21: types.v1.Labels + (*v1.StackTraceSelector)(nil), // 22: types.v1.StackTraceSelector + (v1.TimeSeriesAggregationType)(0), // 23: types.v1.TimeSeriesAggregationType + (*v1.Series)(nil), // 24: types.v1.Series + (*v1.LabelValuesRequest)(nil), // 25: types.v1.LabelValuesRequest + (*v1.LabelNamesRequest)(nil), // 26: types.v1.LabelNamesRequest + (*v1.GetProfileStatsRequest)(nil), // 27: types.v1.GetProfileStatsRequest + (*v1.LabelValuesResponse)(nil), // 28: types.v1.LabelValuesResponse + (*v1.LabelNamesResponse)(nil), // 29: types.v1.LabelNamesResponse + (*v11.Profile)(nil), // 30: google.v1.Profile + (*v1.GetProfileStatsResponse)(nil), // 31: types.v1.GetProfileStatsResponse } var file_querier_v1_querier_proto_depIdxs = []int32{ - 16, // 0: querier.v1.ProfileTypesResponse.profile_types:type_name -> types.v1.ProfileType - 17, // 1: querier.v1.SeriesResponse.labels_set:type_name -> types.v1.Labels + 20, // 0: querier.v1.ProfileTypesResponse.profile_types:type_name -> types.v1.ProfileType + 21, // 1: querier.v1.SeriesResponse.labels_set:type_name -> types.v1.Labels 10, // 2: querier.v1.SelectMergeStacktracesResponse.flamegraph:type_name -> querier.v1.FlameGraph 10, // 3: querier.v1.SelectMergeSpanProfileResponse.flamegraph:type_name -> querier.v1.FlameGraph 4, // 4: querier.v1.DiffRequest.left:type_name -> querier.v1.SelectMergeStacktracesRequest @@ -1341,35 +1689,39 @@ var file_querier_v1_querier_proto_depIdxs = []int32{ 11, // 6: querier.v1.DiffResponse.flamegraph:type_name -> querier.v1.FlameGraphDiff 12, // 7: querier.v1.FlameGraph.levels:type_name -> querier.v1.Level 12, // 8: querier.v1.FlameGraphDiff.levels:type_name -> querier.v1.Level - 18, // 9: querier.v1.SelectMergeProfileRequest.stack_trace_selector:type_name -> types.v1.StackTraceSelector - 19, // 10: querier.v1.SelectSeriesRequest.aggregation:type_name -> types.v1.TimeSeriesAggregationType - 18, // 11: querier.v1.SelectSeriesRequest.stack_trace_selector:type_name -> types.v1.StackTraceSelector - 20, // 12: querier.v1.SelectSeriesResponse.series:type_name -> types.v1.Series - 0, // 13: querier.v1.QuerierService.ProfileTypes:input_type -> querier.v1.ProfileTypesRequest - 21, // 14: querier.v1.QuerierService.LabelValues:input_type -> types.v1.LabelValuesRequest - 22, // 15: querier.v1.QuerierService.LabelNames:input_type -> types.v1.LabelNamesRequest - 2, // 16: querier.v1.QuerierService.Series:input_type -> querier.v1.SeriesRequest - 4, // 17: querier.v1.QuerierService.SelectMergeStacktraces:input_type -> querier.v1.SelectMergeStacktracesRequest - 6, // 18: querier.v1.QuerierService.SelectMergeSpanProfile:input_type -> querier.v1.SelectMergeSpanProfileRequest - 13, // 19: querier.v1.QuerierService.SelectMergeProfile:input_type -> querier.v1.SelectMergeProfileRequest - 14, // 20: querier.v1.QuerierService.SelectSeries:input_type -> querier.v1.SelectSeriesRequest - 8, // 21: querier.v1.QuerierService.Diff:input_type -> querier.v1.DiffRequest - 23, // 22: querier.v1.QuerierService.GetProfileStats:input_type -> types.v1.GetProfileStatsRequest - 1, // 23: querier.v1.QuerierService.ProfileTypes:output_type -> querier.v1.ProfileTypesResponse - 24, // 24: querier.v1.QuerierService.LabelValues:output_type -> types.v1.LabelValuesResponse - 25, // 25: querier.v1.QuerierService.LabelNames:output_type -> types.v1.LabelNamesResponse - 3, // 26: querier.v1.QuerierService.Series:output_type -> querier.v1.SeriesResponse - 5, // 27: querier.v1.QuerierService.SelectMergeStacktraces:output_type -> querier.v1.SelectMergeStacktracesResponse - 7, // 28: querier.v1.QuerierService.SelectMergeSpanProfile:output_type -> querier.v1.SelectMergeSpanProfileResponse - 26, // 29: querier.v1.QuerierService.SelectMergeProfile:output_type -> google.v1.Profile - 15, // 30: querier.v1.QuerierService.SelectSeries:output_type -> querier.v1.SelectSeriesResponse - 9, // 31: querier.v1.QuerierService.Diff:output_type -> querier.v1.DiffResponse - 27, // 32: querier.v1.QuerierService.GetProfileStats:output_type -> types.v1.GetProfileStatsResponse - 23, // [23:33] is the sub-list for method output_type - 13, // [13:23] is the sub-list for method input_type - 13, // [13:13] is the sub-list for extension type_name - 13, // [13:13] is the sub-list for extension extendee - 0, // [0:13] is the sub-list for field type_name + 22, // 9: querier.v1.SelectMergeProfileRequest.stack_trace_selector:type_name -> types.v1.StackTraceSelector + 23, // 10: querier.v1.SelectSeriesRequest.aggregation:type_name -> types.v1.TimeSeriesAggregationType + 22, // 11: querier.v1.SelectSeriesRequest.stack_trace_selector:type_name -> types.v1.StackTraceSelector + 24, // 12: querier.v1.SelectSeriesResponse.series:type_name -> types.v1.Series + 18, // 13: querier.v1.AnalyzeQueryResponse.query_scopes:type_name -> querier.v1.QueryScope + 19, // 14: querier.v1.AnalyzeQueryResponse.query_impact:type_name -> querier.v1.QueryImpact + 0, // 15: querier.v1.QuerierService.ProfileTypes:input_type -> querier.v1.ProfileTypesRequest + 25, // 16: querier.v1.QuerierService.LabelValues:input_type -> types.v1.LabelValuesRequest + 26, // 17: querier.v1.QuerierService.LabelNames:input_type -> types.v1.LabelNamesRequest + 2, // 18: querier.v1.QuerierService.Series:input_type -> querier.v1.SeriesRequest + 4, // 19: querier.v1.QuerierService.SelectMergeStacktraces:input_type -> querier.v1.SelectMergeStacktracesRequest + 6, // 20: querier.v1.QuerierService.SelectMergeSpanProfile:input_type -> querier.v1.SelectMergeSpanProfileRequest + 13, // 21: querier.v1.QuerierService.SelectMergeProfile:input_type -> querier.v1.SelectMergeProfileRequest + 14, // 22: querier.v1.QuerierService.SelectSeries:input_type -> querier.v1.SelectSeriesRequest + 8, // 23: querier.v1.QuerierService.Diff:input_type -> querier.v1.DiffRequest + 27, // 24: querier.v1.QuerierService.GetProfileStats:input_type -> types.v1.GetProfileStatsRequest + 16, // 25: querier.v1.QuerierService.AnalyzeQuery:input_type -> querier.v1.AnalyzeQueryRequest + 1, // 26: querier.v1.QuerierService.ProfileTypes:output_type -> querier.v1.ProfileTypesResponse + 28, // 27: querier.v1.QuerierService.LabelValues:output_type -> types.v1.LabelValuesResponse + 29, // 28: querier.v1.QuerierService.LabelNames:output_type -> types.v1.LabelNamesResponse + 3, // 29: querier.v1.QuerierService.Series:output_type -> querier.v1.SeriesResponse + 5, // 30: querier.v1.QuerierService.SelectMergeStacktraces:output_type -> querier.v1.SelectMergeStacktracesResponse + 7, // 31: querier.v1.QuerierService.SelectMergeSpanProfile:output_type -> querier.v1.SelectMergeSpanProfileResponse + 30, // 32: querier.v1.QuerierService.SelectMergeProfile:output_type -> google.v1.Profile + 15, // 33: querier.v1.QuerierService.SelectSeries:output_type -> querier.v1.SelectSeriesResponse + 9, // 34: querier.v1.QuerierService.Diff:output_type -> querier.v1.DiffResponse + 31, // 35: querier.v1.QuerierService.GetProfileStats:output_type -> types.v1.GetProfileStatsResponse + 17, // 36: querier.v1.QuerierService.AnalyzeQuery:output_type -> querier.v1.AnalyzeQueryResponse + 26, // [26:37] is the sub-list for method output_type + 15, // [15:26] is the sub-list for method input_type + 15, // [15:15] is the sub-list for extension type_name + 15, // [15:15] is the sub-list for extension extendee + 0, // [0:15] is the sub-list for field type_name } func init() { file_querier_v1_querier_proto_init() } @@ -1570,6 +1922,54 @@ func file_querier_v1_querier_proto_init() { return nil } } + file_querier_v1_querier_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AnalyzeQueryRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_querier_v1_querier_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AnalyzeQueryResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_querier_v1_querier_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryScope); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_querier_v1_querier_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryImpact); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_querier_v1_querier_proto_msgTypes[4].OneofWrappers = []interface{}{} file_querier_v1_querier_proto_msgTypes[6].OneofWrappers = []interface{}{} @@ -1581,7 +1981,7 @@ func file_querier_v1_querier_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_querier_v1_querier_proto_rawDesc, NumEnums: 0, - NumMessages: 16, + NumMessages: 20, NumExtensions: 0, NumServices: 1, }, diff --git a/api/gen/proto/go/querier/v1/querier_vtproto.pb.go b/api/gen/proto/go/querier/v1/querier_vtproto.pb.go index ce2014cc6b..c5fbef6779 100644 --- a/api/gen/proto/go/querier/v1/querier_vtproto.pb.go +++ b/api/gen/proto/go/querier/v1/querier_vtproto.pb.go @@ -439,6 +439,97 @@ func (m *SelectSeriesResponse) CloneMessageVT() proto.Message { return m.CloneVT() } +func (m *AnalyzeQueryRequest) CloneVT() *AnalyzeQueryRequest { + if m == nil { + return (*AnalyzeQueryRequest)(nil) + } + r := &AnalyzeQueryRequest{ + Start: m.Start, + End: m.End, + Query: m.Query, + } + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *AnalyzeQueryRequest) CloneMessageVT() proto.Message { + return m.CloneVT() +} + +func (m *AnalyzeQueryResponse) CloneVT() *AnalyzeQueryResponse { + if m == nil { + return (*AnalyzeQueryResponse)(nil) + } + r := &AnalyzeQueryResponse{ + QueryImpact: m.QueryImpact.CloneVT(), + } + if rhs := m.QueryScopes; rhs != nil { + tmpContainer := make([]*QueryScope, len(rhs)) + for k, v := range rhs { + tmpContainer[k] = v.CloneVT() + } + r.QueryScopes = tmpContainer + } + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *AnalyzeQueryResponse) CloneMessageVT() proto.Message { + return m.CloneVT() +} + +func (m *QueryScope) CloneVT() *QueryScope { + if m == nil { + return (*QueryScope)(nil) + } + r := &QueryScope{ + ComponentType: m.ComponentType, + ComponentCount: m.ComponentCount, + BlockCount: m.BlockCount, + SeriesCount: m.SeriesCount, + ProfileCount: m.ProfileCount, + SampleCount: m.SampleCount, + IndexBytes: m.IndexBytes, + ProfileBytes: m.ProfileBytes, + SymbolBytes: m.SymbolBytes, + } + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *QueryScope) CloneMessageVT() proto.Message { + return m.CloneVT() +} + +func (m *QueryImpact) CloneVT() *QueryImpact { + if m == nil { + return (*QueryImpact)(nil) + } + r := &QueryImpact{ + TotalBytesInTimeRange: m.TotalBytesInTimeRange, + TotalQueriedSeries: m.TotalQueriedSeries, + DeduplicationNeeded: m.DeduplicationNeeded, + } + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *QueryImpact) CloneMessageVT() proto.Message { + return m.CloneVT() +} + func (this *ProfileTypesRequest) EqualVT(that *ProfileTypesRequest) bool { if this == that { return true @@ -981,6 +1072,135 @@ func (this *SelectSeriesResponse) EqualMessageVT(thatMsg proto.Message) bool { } return this.EqualVT(that) } +func (this *AnalyzeQueryRequest) EqualVT(that *AnalyzeQueryRequest) bool { + if this == that { + return true + } else if this == nil || that == nil { + return false + } + if this.Start != that.Start { + return false + } + if this.End != that.End { + return false + } + if this.Query != that.Query { + return false + } + return string(this.unknownFields) == string(that.unknownFields) +} + +func (this *AnalyzeQueryRequest) EqualMessageVT(thatMsg proto.Message) bool { + that, ok := thatMsg.(*AnalyzeQueryRequest) + if !ok { + return false + } + return this.EqualVT(that) +} +func (this *AnalyzeQueryResponse) EqualVT(that *AnalyzeQueryResponse) bool { + if this == that { + return true + } else if this == nil || that == nil { + return false + } + if len(this.QueryScopes) != len(that.QueryScopes) { + return false + } + for i, vx := range this.QueryScopes { + vy := that.QueryScopes[i] + if p, q := vx, vy; p != q { + if p == nil { + p = &QueryScope{} + } + if q == nil { + q = &QueryScope{} + } + if !p.EqualVT(q) { + return false + } + } + } + if !this.QueryImpact.EqualVT(that.QueryImpact) { + return false + } + return string(this.unknownFields) == string(that.unknownFields) +} + +func (this *AnalyzeQueryResponse) EqualMessageVT(thatMsg proto.Message) bool { + that, ok := thatMsg.(*AnalyzeQueryResponse) + if !ok { + return false + } + return this.EqualVT(that) +} +func (this *QueryScope) EqualVT(that *QueryScope) bool { + if this == that { + return true + } else if this == nil || that == nil { + return false + } + if this.ComponentType != that.ComponentType { + return false + } + if this.ComponentCount != that.ComponentCount { + return false + } + if this.BlockCount != that.BlockCount { + return false + } + if this.SeriesCount != that.SeriesCount { + return false + } + if this.ProfileCount != that.ProfileCount { + return false + } + if this.SampleCount != that.SampleCount { + return false + } + if this.IndexBytes != that.IndexBytes { + return false + } + if this.ProfileBytes != that.ProfileBytes { + return false + } + if this.SymbolBytes != that.SymbolBytes { + return false + } + return string(this.unknownFields) == string(that.unknownFields) +} + +func (this *QueryScope) EqualMessageVT(thatMsg proto.Message) bool { + that, ok := thatMsg.(*QueryScope) + if !ok { + return false + } + return this.EqualVT(that) +} +func (this *QueryImpact) EqualVT(that *QueryImpact) bool { + if this == that { + return true + } else if this == nil || that == nil { + return false + } + if this.TotalBytesInTimeRange != that.TotalBytesInTimeRange { + return false + } + if this.TotalQueriedSeries != that.TotalQueriedSeries { + return false + } + if this.DeduplicationNeeded != that.DeduplicationNeeded { + return false + } + return string(this.unknownFields) == string(that.unknownFields) +} + +func (this *QueryImpact) EqualMessageVT(thatMsg proto.Message) bool { + that, ok := thatMsg.(*QueryImpact) + if !ok { + return false + } + return this.EqualVT(that) +} // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. @@ -1011,6 +1231,7 @@ type QuerierServiceClient interface { Diff(ctx context.Context, in *DiffRequest, opts ...grpc.CallOption) (*DiffResponse, error) // GetProfileStats returns profile stats for the current tenant. GetProfileStats(ctx context.Context, in *v1.GetProfileStatsRequest, opts ...grpc.CallOption) (*v1.GetProfileStatsResponse, error) + AnalyzeQuery(ctx context.Context, in *AnalyzeQueryRequest, opts ...grpc.CallOption) (*AnalyzeQueryResponse, error) } type querierServiceClient struct { @@ -1111,6 +1332,15 @@ func (c *querierServiceClient) GetProfileStats(ctx context.Context, in *v1.GetPr return out, nil } +func (c *querierServiceClient) AnalyzeQuery(ctx context.Context, in *AnalyzeQueryRequest, opts ...grpc.CallOption) (*AnalyzeQueryResponse, error) { + out := new(AnalyzeQueryResponse) + err := c.cc.Invoke(ctx, "/querier.v1.QuerierService/AnalyzeQuery", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // QuerierServiceServer is the server API for QuerierService service. // All implementations must embed UnimplementedQuerierServiceServer // for forward compatibility @@ -1135,6 +1365,7 @@ type QuerierServiceServer interface { Diff(context.Context, *DiffRequest) (*DiffResponse, error) // GetProfileStats returns profile stats for the current tenant. GetProfileStats(context.Context, *v1.GetProfileStatsRequest) (*v1.GetProfileStatsResponse, error) + AnalyzeQuery(context.Context, *AnalyzeQueryRequest) (*AnalyzeQueryResponse, error) mustEmbedUnimplementedQuerierServiceServer() } @@ -1172,6 +1403,9 @@ func (UnimplementedQuerierServiceServer) Diff(context.Context, *DiffRequest) (*D func (UnimplementedQuerierServiceServer) GetProfileStats(context.Context, *v1.GetProfileStatsRequest) (*v1.GetProfileStatsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetProfileStats not implemented") } +func (UnimplementedQuerierServiceServer) AnalyzeQuery(context.Context, *AnalyzeQueryRequest) (*AnalyzeQueryResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AnalyzeQuery not implemented") +} func (UnimplementedQuerierServiceServer) mustEmbedUnimplementedQuerierServiceServer() {} // UnsafeQuerierServiceServer may be embedded to opt out of forward compatibility for this service. @@ -1365,6 +1599,24 @@ func _QuerierService_GetProfileStats_Handler(srv interface{}, ctx context.Contex return interceptor(ctx, in, info, handler) } +func _QuerierService_AnalyzeQuery_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AnalyzeQueryRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QuerierServiceServer).AnalyzeQuery(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/querier.v1.QuerierService/AnalyzeQuery", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QuerierServiceServer).AnalyzeQuery(ctx, req.(*AnalyzeQueryRequest)) + } + return interceptor(ctx, in, info, handler) +} + // QuerierService_ServiceDesc is the grpc.ServiceDesc for QuerierService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -1412,6 +1664,10 @@ var QuerierService_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetProfileStats", Handler: _QuerierService_GetProfileStats_Handler, }, + { + MethodName: "AnalyzeQuery", + Handler: _QuerierService_AnalyzeQuery_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "querier/v1/querier.proto", @@ -2382,60 +2638,298 @@ func (m *SelectSeriesResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) return len(dAtA) - i, nil } -func encodeVarint(dAtA []byte, offset int, v uint64) int { - offset -= sov(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ +func (m *AnalyzeQueryRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil } - dAtA[offset] = uint8(v) - return base + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil } -func (m *ProfileTypesRequest) SizeVT() (n int) { + +func (m *AnalyzeQueryRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *AnalyzeQueryRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if m == nil { - return 0 + return 0, nil } + i := len(dAtA) + _ = i var l int _ = l - if m.Start != 0 { - n += 1 + sov(uint64(m.Start)) + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Query) > 0 { + i -= len(m.Query) + copy(dAtA[i:], m.Query) + i = encodeVarint(dAtA, i, uint64(len(m.Query))) + i-- + dAtA[i] = 0x22 } if m.End != 0 { - n += 1 + sov(uint64(m.End)) + i = encodeVarint(dAtA, i, uint64(m.End)) + i-- + dAtA[i] = 0x18 } - n += len(m.unknownFields) - return n + if m.Start != 0 { + i = encodeVarint(dAtA, i, uint64(m.Start)) + i-- + dAtA[i] = 0x10 + } + return len(dAtA) - i, nil } -func (m *ProfileTypesResponse) SizeVT() (n int) { +func (m *AnalyzeQueryResponse) MarshalVT() (dAtA []byte, err error) { if m == nil { - return 0 + return nil, nil } - var l int - _ = l - if len(m.ProfileTypes) > 0 { - for _, e := range m.ProfileTypes { - if size, ok := interface{}(e).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(e) - } - n += 1 + l + sov(uint64(l)) - } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err } - n += len(m.unknownFields) - return n + return dAtA[:n], nil } -func (m *SeriesRequest) SizeVT() (n int) { +func (m *AnalyzeQueryResponse) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *AnalyzeQueryResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if m == nil { - return 0 + return 0, nil } - var l int + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.QueryImpact != nil { + size, err := m.QueryImpact.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x12 + } + if len(m.QueryScopes) > 0 { + for iNdEx := len(m.QueryScopes) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.QueryScopes[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryScope) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryScope) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *QueryScope) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.SymbolBytes != 0 { + i = encodeVarint(dAtA, i, uint64(m.SymbolBytes)) + i-- + dAtA[i] = 0x48 + } + if m.ProfileBytes != 0 { + i = encodeVarint(dAtA, i, uint64(m.ProfileBytes)) + i-- + dAtA[i] = 0x40 + } + if m.IndexBytes != 0 { + i = encodeVarint(dAtA, i, uint64(m.IndexBytes)) + i-- + dAtA[i] = 0x38 + } + if m.SampleCount != 0 { + i = encodeVarint(dAtA, i, uint64(m.SampleCount)) + i-- + dAtA[i] = 0x30 + } + if m.ProfileCount != 0 { + i = encodeVarint(dAtA, i, uint64(m.ProfileCount)) + i-- + dAtA[i] = 0x28 + } + if m.SeriesCount != 0 { + i = encodeVarint(dAtA, i, uint64(m.SeriesCount)) + i-- + dAtA[i] = 0x20 + } + if m.BlockCount != 0 { + i = encodeVarint(dAtA, i, uint64(m.BlockCount)) + i-- + dAtA[i] = 0x18 + } + if m.ComponentCount != 0 { + i = encodeVarint(dAtA, i, uint64(m.ComponentCount)) + i-- + dAtA[i] = 0x10 + } + if len(m.ComponentType) > 0 { + i -= len(m.ComponentType) + copy(dAtA[i:], m.ComponentType) + i = encodeVarint(dAtA, i, uint64(len(m.ComponentType))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryImpact) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryImpact) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *QueryImpact) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.DeduplicationNeeded { + i-- + if m.DeduplicationNeeded { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x20 + } + if m.TotalQueriedSeries != 0 { + i = encodeVarint(dAtA, i, uint64(m.TotalQueriedSeries)) + i-- + dAtA[i] = 0x18 + } + if m.TotalBytesInTimeRange != 0 { + i = encodeVarint(dAtA, i, uint64(m.TotalBytesInTimeRange)) + i-- + dAtA[i] = 0x10 + } + return len(dAtA) - i, nil +} + +func encodeVarint(dAtA []byte, offset int, v uint64) int { + offset -= sov(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *ProfileTypesRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Start != 0 { + n += 1 + sov(uint64(m.Start)) + } + if m.End != 0 { + n += 1 + sov(uint64(m.End)) + } + n += len(m.unknownFields) + return n +} + +func (m *ProfileTypesResponse) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.ProfileTypes) > 0 { + for _, e := range m.ProfileTypes { + if size, ok := interface{}(e).(interface { + SizeVT() int + }); ok { + l = size.SizeVT() + } else { + l = proto.Size(e) + } + n += 1 + l + sov(uint64(l)) + } + } + n += len(m.unknownFields) + return n +} + +func (m *SeriesRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int _ = l if len(m.Matchers) > 0 { for _, s := range m.Matchers { @@ -2785,6 +3279,103 @@ func (m *SelectSeriesResponse) SizeVT() (n int) { return n } +func (m *AnalyzeQueryRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Start != 0 { + n += 1 + sov(uint64(m.Start)) + } + if m.End != 0 { + n += 1 + sov(uint64(m.End)) + } + l = len(m.Query) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *AnalyzeQueryResponse) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.QueryScopes) > 0 { + for _, e := range m.QueryScopes { + l = e.SizeVT() + n += 1 + l + sov(uint64(l)) + } + } + if m.QueryImpact != nil { + l = m.QueryImpact.SizeVT() + n += 1 + l + sov(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *QueryScope) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ComponentType) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + if m.ComponentCount != 0 { + n += 1 + sov(uint64(m.ComponentCount)) + } + if m.BlockCount != 0 { + n += 1 + sov(uint64(m.BlockCount)) + } + if m.SeriesCount != 0 { + n += 1 + sov(uint64(m.SeriesCount)) + } + if m.ProfileCount != 0 { + n += 1 + sov(uint64(m.ProfileCount)) + } + if m.SampleCount != 0 { + n += 1 + sov(uint64(m.SampleCount)) + } + if m.IndexBytes != 0 { + n += 1 + sov(uint64(m.IndexBytes)) + } + if m.ProfileBytes != 0 { + n += 1 + sov(uint64(m.ProfileBytes)) + } + if m.SymbolBytes != 0 { + n += 1 + sov(uint64(m.SymbolBytes)) + } + n += len(m.unknownFields) + return n +} + +func (m *QueryImpact) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.TotalBytesInTimeRange != 0 { + n += 1 + sov(uint64(m.TotalBytesInTimeRange)) + } + if m.TotalQueriedSeries != 0 { + n += 1 + sov(uint64(m.TotalQueriedSeries)) + } + if m.DeduplicationNeeded { + n += 2 + } + n += len(m.unknownFields) + return n +} + func sov(x uint64) (n int) { return (bits.Len64(x|1) + 6) / 7 } @@ -5026,6 +5617,592 @@ func (m *SelectSeriesResponse) UnmarshalVT(dAtA []byte) error { } return nil } +func (m *AnalyzeQueryRequest) UnmarshalVT(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 ErrIntOverflow + } + 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: AnalyzeQueryRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AnalyzeQueryRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Start", wireType) + } + m.Start = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Start |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field End", wireType) + } + m.End = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.End |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Query", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Query = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AnalyzeQueryResponse) UnmarshalVT(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 ErrIntOverflow + } + 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: AnalyzeQueryResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AnalyzeQueryResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field QueryScopes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.QueryScopes = append(m.QueryScopes, &QueryScope{}) + if err := m.QueryScopes[len(m.QueryScopes)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field QueryImpact", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.QueryImpact == nil { + m.QueryImpact = &QueryImpact{} + } + if err := m.QueryImpact.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryScope) UnmarshalVT(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 ErrIntOverflow + } + 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: QueryScope: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryScope: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ComponentType", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ComponentType = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ComponentCount", wireType) + } + m.ComponentCount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ComponentCount |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockCount", wireType) + } + m.BlockCount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.BlockCount |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SeriesCount", wireType) + } + m.SeriesCount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SeriesCount |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ProfileCount", wireType) + } + m.ProfileCount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ProfileCount |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SampleCount", wireType) + } + m.SampleCount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SampleCount |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IndexBytes", wireType) + } + m.IndexBytes = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.IndexBytes |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ProfileBytes", wireType) + } + m.ProfileBytes = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ProfileBytes |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SymbolBytes", wireType) + } + m.SymbolBytes = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SymbolBytes |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryImpact) UnmarshalVT(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 ErrIntOverflow + } + 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: QueryImpact: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryImpact: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalBytesInTimeRange", wireType) + } + m.TotalBytesInTimeRange = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TotalBytesInTimeRange |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalQueriedSeries", wireType) + } + m.TotalQueriedSeries = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TotalQueriedSeries |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DeduplicationNeeded", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.DeduplicationNeeded = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skip(dAtA []byte) (n int, err error) { l := len(dAtA) diff --git a/api/gen/proto/go/querier/v1/querierv1connect/querier.connect.go b/api/gen/proto/go/querier/v1/querierv1connect/querier.connect.go index 6ee89563c0..fcf4bd79c3 100644 --- a/api/gen/proto/go/querier/v1/querierv1connect/querier.connect.go +++ b/api/gen/proto/go/querier/v1/querierv1connect/querier.connect.go @@ -63,6 +63,9 @@ const ( // QuerierServiceGetProfileStatsProcedure is the fully-qualified name of the QuerierService's // GetProfileStats RPC. QuerierServiceGetProfileStatsProcedure = "/querier.v1.QuerierService/GetProfileStats" + // QuerierServiceAnalyzeQueryProcedure is the fully-qualified name of the QuerierService's + // AnalyzeQuery RPC. + QuerierServiceAnalyzeQueryProcedure = "/querier.v1.QuerierService/AnalyzeQuery" ) // These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. @@ -78,6 +81,7 @@ var ( querierServiceSelectSeriesMethodDescriptor = querierServiceServiceDescriptor.Methods().ByName("SelectSeries") querierServiceDiffMethodDescriptor = querierServiceServiceDescriptor.Methods().ByName("Diff") querierServiceGetProfileStatsMethodDescriptor = querierServiceServiceDescriptor.Methods().ByName("GetProfileStats") + querierServiceAnalyzeQueryMethodDescriptor = querierServiceServiceDescriptor.Methods().ByName("AnalyzeQuery") ) // QuerierServiceClient is a client for the querier.v1.QuerierService service. @@ -102,6 +106,7 @@ type QuerierServiceClient interface { Diff(context.Context, *connect.Request[v1.DiffRequest]) (*connect.Response[v1.DiffResponse], error) // GetProfileStats returns profile stats for the current tenant. GetProfileStats(context.Context, *connect.Request[v11.GetProfileStatsRequest]) (*connect.Response[v11.GetProfileStatsResponse], error) + AnalyzeQuery(context.Context, *connect.Request[v1.AnalyzeQueryRequest]) (*connect.Response[v1.AnalyzeQueryResponse], error) } // NewQuerierServiceClient constructs a client for the querier.v1.QuerierService service. By @@ -174,6 +179,12 @@ func NewQuerierServiceClient(httpClient connect.HTTPClient, baseURL string, opts connect.WithSchema(querierServiceGetProfileStatsMethodDescriptor), connect.WithClientOptions(opts...), ), + analyzeQuery: connect.NewClient[v1.AnalyzeQueryRequest, v1.AnalyzeQueryResponse]( + httpClient, + baseURL+QuerierServiceAnalyzeQueryProcedure, + connect.WithSchema(querierServiceAnalyzeQueryMethodDescriptor), + connect.WithClientOptions(opts...), + ), } } @@ -189,6 +200,7 @@ type querierServiceClient struct { selectSeries *connect.Client[v1.SelectSeriesRequest, v1.SelectSeriesResponse] diff *connect.Client[v1.DiffRequest, v1.DiffResponse] getProfileStats *connect.Client[v11.GetProfileStatsRequest, v11.GetProfileStatsResponse] + analyzeQuery *connect.Client[v1.AnalyzeQueryRequest, v1.AnalyzeQueryResponse] } // ProfileTypes calls querier.v1.QuerierService.ProfileTypes. @@ -241,6 +253,11 @@ func (c *querierServiceClient) GetProfileStats(ctx context.Context, req *connect return c.getProfileStats.CallUnary(ctx, req) } +// AnalyzeQuery calls querier.v1.QuerierService.AnalyzeQuery. +func (c *querierServiceClient) AnalyzeQuery(ctx context.Context, req *connect.Request[v1.AnalyzeQueryRequest]) (*connect.Response[v1.AnalyzeQueryResponse], error) { + return c.analyzeQuery.CallUnary(ctx, req) +} + // QuerierServiceHandler is an implementation of the querier.v1.QuerierService service. type QuerierServiceHandler interface { // ProfileType returns a list of the existing profile types. @@ -263,6 +280,7 @@ type QuerierServiceHandler interface { Diff(context.Context, *connect.Request[v1.DiffRequest]) (*connect.Response[v1.DiffResponse], error) // GetProfileStats returns profile stats for the current tenant. GetProfileStats(context.Context, *connect.Request[v11.GetProfileStatsRequest]) (*connect.Response[v11.GetProfileStatsResponse], error) + AnalyzeQuery(context.Context, *connect.Request[v1.AnalyzeQueryRequest]) (*connect.Response[v1.AnalyzeQueryResponse], error) } // NewQuerierServiceHandler builds an HTTP handler from the service implementation. It returns the @@ -331,6 +349,12 @@ func NewQuerierServiceHandler(svc QuerierServiceHandler, opts ...connect.Handler connect.WithSchema(querierServiceGetProfileStatsMethodDescriptor), connect.WithHandlerOptions(opts...), ) + querierServiceAnalyzeQueryHandler := connect.NewUnaryHandler( + QuerierServiceAnalyzeQueryProcedure, + svc.AnalyzeQuery, + connect.WithSchema(querierServiceAnalyzeQueryMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) return "/querier.v1.QuerierService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { case QuerierServiceProfileTypesProcedure: @@ -353,6 +377,8 @@ func NewQuerierServiceHandler(svc QuerierServiceHandler, opts ...connect.Handler querierServiceDiffHandler.ServeHTTP(w, r) case QuerierServiceGetProfileStatsProcedure: querierServiceGetProfileStatsHandler.ServeHTTP(w, r) + case QuerierServiceAnalyzeQueryProcedure: + querierServiceAnalyzeQueryHandler.ServeHTTP(w, r) default: http.NotFound(w, r) } @@ -401,3 +427,7 @@ func (UnimplementedQuerierServiceHandler) Diff(context.Context, *connect.Request func (UnimplementedQuerierServiceHandler) GetProfileStats(context.Context, *connect.Request[v11.GetProfileStatsRequest]) (*connect.Response[v11.GetProfileStatsResponse], error) { return nil, connect.NewError(connect.CodeUnimplemented, errors.New("querier.v1.QuerierService.GetProfileStats is not implemented")) } + +func (UnimplementedQuerierServiceHandler) AnalyzeQuery(context.Context, *connect.Request[v1.AnalyzeQueryRequest]) (*connect.Response[v1.AnalyzeQueryResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("querier.v1.QuerierService.AnalyzeQuery is not implemented")) +} diff --git a/api/gen/proto/go/querier/v1/querierv1connect/querier.connect.mux.go b/api/gen/proto/go/querier/v1/querierv1connect/querier.connect.mux.go index f94c88c3c9..9a82702031 100644 --- a/api/gen/proto/go/querier/v1/querierv1connect/querier.connect.mux.go +++ b/api/gen/proto/go/querier/v1/querierv1connect/querier.connect.mux.go @@ -69,4 +69,9 @@ func RegisterQuerierServiceHandler(mux *mux.Router, svc QuerierServiceHandler, o svc.GetProfileStats, opts..., )) + mux.Handle("/querier.v1.QuerierService/AnalyzeQuery", connect.NewUnaryHandler( + "/querier.v1.QuerierService/AnalyzeQuery", + svc.AnalyzeQuery, + opts..., + )) } diff --git a/api/gen/proto/go/storegateway/v1/storegateway.pb.go b/api/gen/proto/go/storegateway/v1/storegateway.pb.go index 264d40e32e..a71ded2c3e 100644 --- a/api/gen/proto/go/storegateway/v1/storegateway.pb.go +++ b/api/gen/proto/go/storegateway/v1/storegateway.pb.go @@ -35,7 +35,7 @@ var file_storegateway_v1_storegateway_proto_rawDesc = []byte{ 0x73, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x12, 0x70, 0x75, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x75, 0x73, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x32, 0xe7, 0x06, 0x0a, 0x13, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x47, 0x61, + 0x72, 0x6f, 0x74, 0x6f, 0x32, 0xc1, 0x07, 0x0a, 0x13, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x7d, 0x0a, 0x18, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x74, 0x72, 0x61, 0x63, 0x65, 0x73, 0x12, 0x2c, 0x2e, 0x69, 0x6e, 0x67, 0x65, 0x73, @@ -89,21 +89,27 @@ var file_storegateway_v1_storegateway_proto_rawDesc = []byte{ 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xd3, - 0x01, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, - 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x42, 0x11, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x67, 0x61, 0x74, - 0x65, 0x77, 0x61, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x4c, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x66, 0x61, 0x6e, 0x61, 0x2f, - 0x70, 0x79, 0x72, 0x6f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, - 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, - 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2f, 0x76, 0x31, 0x3b, 0x73, 0x74, 0x6f, 0x72, 0x65, - 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x53, 0x58, 0x58, 0xaa, - 0x02, 0x0f, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x56, - 0x31, 0xca, 0x02, 0x0f, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, - 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1b, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, - 0x61, 0x79, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0xea, 0x02, 0x10, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, - 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, + 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, + 0x21, 0x2e, 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, + 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x69, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xd3, 0x01, 0x0a, 0x13, 0x63, 0x6f, 0x6d, + 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, + 0x42, 0x11, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x4c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x66, 0x61, 0x6e, 0x61, 0x2f, 0x70, 0x79, 0x72, 0x6f, 0x73, 0x63, + 0x6f, 0x70, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, + 0x79, 0x2f, 0x76, 0x31, 0x3b, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, + 0x79, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x53, 0x58, 0x58, 0xaa, 0x02, 0x0f, 0x53, 0x74, 0x6f, 0x72, + 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0f, 0x53, 0x74, + 0x6f, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1b, + 0x53, 0x74, 0x6f, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5c, 0x56, 0x31, 0x5c, + 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x10, 0x53, 0x74, + 0x6f, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var file_storegateway_v1_storegateway_proto_goTypes = []interface{}{ @@ -116,15 +122,17 @@ var file_storegateway_v1_storegateway_proto_goTypes = []interface{}{ (*v11.LabelNamesRequest)(nil), // 6: types.v1.LabelNamesRequest (*v1.SeriesRequest)(nil), // 7: ingester.v1.SeriesRequest (*v1.BlockMetadataRequest)(nil), // 8: ingester.v1.BlockMetadataRequest - (*v1.MergeProfilesStacktracesResponse)(nil), // 9: ingester.v1.MergeProfilesStacktracesResponse - (*v1.MergeProfilesLabelsResponse)(nil), // 10: ingester.v1.MergeProfilesLabelsResponse - (*v1.MergeProfilesPprofResponse)(nil), // 11: ingester.v1.MergeProfilesPprofResponse - (*v1.MergeSpanProfileResponse)(nil), // 12: ingester.v1.MergeSpanProfileResponse - (*v1.ProfileTypesResponse)(nil), // 13: ingester.v1.ProfileTypesResponse - (*v11.LabelValuesResponse)(nil), // 14: types.v1.LabelValuesResponse - (*v11.LabelNamesResponse)(nil), // 15: types.v1.LabelNamesResponse - (*v1.SeriesResponse)(nil), // 16: ingester.v1.SeriesResponse - (*v1.BlockMetadataResponse)(nil), // 17: ingester.v1.BlockMetadataResponse + (*v1.GetBlockStatsRequest)(nil), // 9: ingester.v1.GetBlockStatsRequest + (*v1.MergeProfilesStacktracesResponse)(nil), // 10: ingester.v1.MergeProfilesStacktracesResponse + (*v1.MergeProfilesLabelsResponse)(nil), // 11: ingester.v1.MergeProfilesLabelsResponse + (*v1.MergeProfilesPprofResponse)(nil), // 12: ingester.v1.MergeProfilesPprofResponse + (*v1.MergeSpanProfileResponse)(nil), // 13: ingester.v1.MergeSpanProfileResponse + (*v1.ProfileTypesResponse)(nil), // 14: ingester.v1.ProfileTypesResponse + (*v11.LabelValuesResponse)(nil), // 15: types.v1.LabelValuesResponse + (*v11.LabelNamesResponse)(nil), // 16: types.v1.LabelNamesResponse + (*v1.SeriesResponse)(nil), // 17: ingester.v1.SeriesResponse + (*v1.BlockMetadataResponse)(nil), // 18: ingester.v1.BlockMetadataResponse + (*v1.GetBlockStatsResponse)(nil), // 19: ingester.v1.GetBlockStatsResponse } var file_storegateway_v1_storegateway_proto_depIdxs = []int32{ 0, // 0: storegateway.v1.StoreGatewayService.MergeProfilesStacktraces:input_type -> ingester.v1.MergeProfilesStacktracesRequest @@ -136,17 +144,19 @@ var file_storegateway_v1_storegateway_proto_depIdxs = []int32{ 6, // 6: storegateway.v1.StoreGatewayService.LabelNames:input_type -> types.v1.LabelNamesRequest 7, // 7: storegateway.v1.StoreGatewayService.Series:input_type -> ingester.v1.SeriesRequest 8, // 8: storegateway.v1.StoreGatewayService.BlockMetadata:input_type -> ingester.v1.BlockMetadataRequest - 9, // 9: storegateway.v1.StoreGatewayService.MergeProfilesStacktraces:output_type -> ingester.v1.MergeProfilesStacktracesResponse - 10, // 10: storegateway.v1.StoreGatewayService.MergeProfilesLabels:output_type -> ingester.v1.MergeProfilesLabelsResponse - 11, // 11: storegateway.v1.StoreGatewayService.MergeProfilesPprof:output_type -> ingester.v1.MergeProfilesPprofResponse - 12, // 12: storegateway.v1.StoreGatewayService.MergeSpanProfile:output_type -> ingester.v1.MergeSpanProfileResponse - 13, // 13: storegateway.v1.StoreGatewayService.ProfileTypes:output_type -> ingester.v1.ProfileTypesResponse - 14, // 14: storegateway.v1.StoreGatewayService.LabelValues:output_type -> types.v1.LabelValuesResponse - 15, // 15: storegateway.v1.StoreGatewayService.LabelNames:output_type -> types.v1.LabelNamesResponse - 16, // 16: storegateway.v1.StoreGatewayService.Series:output_type -> ingester.v1.SeriesResponse - 17, // 17: storegateway.v1.StoreGatewayService.BlockMetadata:output_type -> ingester.v1.BlockMetadataResponse - 9, // [9:18] is the sub-list for method output_type - 0, // [0:9] is the sub-list for method input_type + 9, // 9: storegateway.v1.StoreGatewayService.GetBlockStats:input_type -> ingester.v1.GetBlockStatsRequest + 10, // 10: storegateway.v1.StoreGatewayService.MergeProfilesStacktraces:output_type -> ingester.v1.MergeProfilesStacktracesResponse + 11, // 11: storegateway.v1.StoreGatewayService.MergeProfilesLabels:output_type -> ingester.v1.MergeProfilesLabelsResponse + 12, // 12: storegateway.v1.StoreGatewayService.MergeProfilesPprof:output_type -> ingester.v1.MergeProfilesPprofResponse + 13, // 13: storegateway.v1.StoreGatewayService.MergeSpanProfile:output_type -> ingester.v1.MergeSpanProfileResponse + 14, // 14: storegateway.v1.StoreGatewayService.ProfileTypes:output_type -> ingester.v1.ProfileTypesResponse + 15, // 15: storegateway.v1.StoreGatewayService.LabelValues:output_type -> types.v1.LabelValuesResponse + 16, // 16: storegateway.v1.StoreGatewayService.LabelNames:output_type -> types.v1.LabelNamesResponse + 17, // 17: storegateway.v1.StoreGatewayService.Series:output_type -> ingester.v1.SeriesResponse + 18, // 18: storegateway.v1.StoreGatewayService.BlockMetadata:output_type -> ingester.v1.BlockMetadataResponse + 19, // 19: storegateway.v1.StoreGatewayService.GetBlockStats:output_type -> ingester.v1.GetBlockStatsResponse + 10, // [10:20] is the sub-list for method output_type + 0, // [0:10] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name diff --git a/api/gen/proto/go/storegateway/v1/storegateway_vtproto.pb.go b/api/gen/proto/go/storegateway/v1/storegateway_vtproto.pb.go index bd467178b2..d17dbbb283 100644 --- a/api/gen/proto/go/storegateway/v1/storegateway_vtproto.pb.go +++ b/api/gen/proto/go/storegateway/v1/storegateway_vtproto.pb.go @@ -41,6 +41,7 @@ type StoreGatewayServiceClient interface { LabelNames(ctx context.Context, in *v11.LabelNamesRequest, opts ...grpc.CallOption) (*v11.LabelNamesResponse, error) Series(ctx context.Context, in *v1.SeriesRequest, opts ...grpc.CallOption) (*v1.SeriesResponse, error) BlockMetadata(ctx context.Context, in *v1.BlockMetadataRequest, opts ...grpc.CallOption) (*v1.BlockMetadataResponse, error) + GetBlockStats(ctx context.Context, in *v1.GetBlockStatsRequest, opts ...grpc.CallOption) (*v1.GetBlockStatsResponse, error) } type storeGatewayServiceClient struct { @@ -220,6 +221,15 @@ func (c *storeGatewayServiceClient) BlockMetadata(ctx context.Context, in *v1.Bl return out, nil } +func (c *storeGatewayServiceClient) GetBlockStats(ctx context.Context, in *v1.GetBlockStatsRequest, opts ...grpc.CallOption) (*v1.GetBlockStatsResponse, error) { + out := new(v1.GetBlockStatsResponse) + err := c.cc.Invoke(ctx, "/storegateway.v1.StoreGatewayService/GetBlockStats", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // StoreGatewayServiceServer is the server API for StoreGatewayService service. // All implementations must embed UnimplementedStoreGatewayServiceServer // for forward compatibility @@ -235,6 +245,7 @@ type StoreGatewayServiceServer interface { LabelNames(context.Context, *v11.LabelNamesRequest) (*v11.LabelNamesResponse, error) Series(context.Context, *v1.SeriesRequest) (*v1.SeriesResponse, error) BlockMetadata(context.Context, *v1.BlockMetadataRequest) (*v1.BlockMetadataResponse, error) + GetBlockStats(context.Context, *v1.GetBlockStatsRequest) (*v1.GetBlockStatsResponse, error) mustEmbedUnimplementedStoreGatewayServiceServer() } @@ -269,6 +280,9 @@ func (UnimplementedStoreGatewayServiceServer) Series(context.Context, *v1.Series func (UnimplementedStoreGatewayServiceServer) BlockMetadata(context.Context, *v1.BlockMetadataRequest) (*v1.BlockMetadataResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method BlockMetadata not implemented") } +func (UnimplementedStoreGatewayServiceServer) GetBlockStats(context.Context, *v1.GetBlockStatsRequest) (*v1.GetBlockStatsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetBlockStats not implemented") +} func (UnimplementedStoreGatewayServiceServer) mustEmbedUnimplementedStoreGatewayServiceServer() {} // UnsafeStoreGatewayServiceServer may be embedded to opt out of forward compatibility for this service. @@ -476,6 +490,24 @@ func _StoreGatewayService_BlockMetadata_Handler(srv interface{}, ctx context.Con return interceptor(ctx, in, info, handler) } +func _StoreGatewayService_GetBlockStats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(v1.GetBlockStatsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StoreGatewayServiceServer).GetBlockStats(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/storegateway.v1.StoreGatewayService/GetBlockStats", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StoreGatewayServiceServer).GetBlockStats(ctx, req.(*v1.GetBlockStatsRequest)) + } + return interceptor(ctx, in, info, handler) +} + // StoreGatewayService_ServiceDesc is the grpc.ServiceDesc for StoreGatewayService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -503,6 +535,10 @@ var StoreGatewayService_ServiceDesc = grpc.ServiceDesc{ MethodName: "BlockMetadata", Handler: _StoreGatewayService_BlockMetadata_Handler, }, + { + MethodName: "GetBlockStats", + Handler: _StoreGatewayService_GetBlockStats_Handler, + }, }, Streams: []grpc.StreamDesc{ { diff --git a/api/gen/proto/go/storegateway/v1/storegatewayv1connect/storegateway.connect.go b/api/gen/proto/go/storegateway/v1/storegatewayv1connect/storegateway.connect.go index 835ac5de0d..c92896ddb6 100644 --- a/api/gen/proto/go/storegateway/v1/storegatewayv1connect/storegateway.connect.go +++ b/api/gen/proto/go/storegateway/v1/storegatewayv1connect/storegateway.connect.go @@ -62,6 +62,9 @@ const ( // StoreGatewayServiceBlockMetadataProcedure is the fully-qualified name of the // StoreGatewayService's BlockMetadata RPC. StoreGatewayServiceBlockMetadataProcedure = "/storegateway.v1.StoreGatewayService/BlockMetadata" + // StoreGatewayServiceGetBlockStatsProcedure is the fully-qualified name of the + // StoreGatewayService's GetBlockStats RPC. + StoreGatewayServiceGetBlockStatsProcedure = "/storegateway.v1.StoreGatewayService/GetBlockStats" ) // These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. @@ -76,6 +79,7 @@ var ( storeGatewayServiceLabelNamesMethodDescriptor = storeGatewayServiceServiceDescriptor.Methods().ByName("LabelNames") storeGatewayServiceSeriesMethodDescriptor = storeGatewayServiceServiceDescriptor.Methods().ByName("Series") storeGatewayServiceBlockMetadataMethodDescriptor = storeGatewayServiceServiceDescriptor.Methods().ByName("BlockMetadata") + storeGatewayServiceGetBlockStatsMethodDescriptor = storeGatewayServiceServiceDescriptor.Methods().ByName("GetBlockStats") ) // StoreGatewayServiceClient is a client for the storegateway.v1.StoreGatewayService service. @@ -91,6 +95,7 @@ type StoreGatewayServiceClient interface { LabelNames(context.Context, *connect.Request[v12.LabelNamesRequest]) (*connect.Response[v12.LabelNamesResponse], error) Series(context.Context, *connect.Request[v11.SeriesRequest]) (*connect.Response[v11.SeriesResponse], error) BlockMetadata(context.Context, *connect.Request[v11.BlockMetadataRequest]) (*connect.Response[v11.BlockMetadataResponse], error) + GetBlockStats(context.Context, *connect.Request[v11.GetBlockStatsRequest]) (*connect.Response[v11.GetBlockStatsResponse], error) } // NewStoreGatewayServiceClient constructs a client for the storegateway.v1.StoreGatewayService @@ -157,6 +162,12 @@ func NewStoreGatewayServiceClient(httpClient connect.HTTPClient, baseURL string, connect.WithSchema(storeGatewayServiceBlockMetadataMethodDescriptor), connect.WithClientOptions(opts...), ), + getBlockStats: connect.NewClient[v11.GetBlockStatsRequest, v11.GetBlockStatsResponse]( + httpClient, + baseURL+StoreGatewayServiceGetBlockStatsProcedure, + connect.WithSchema(storeGatewayServiceGetBlockStatsMethodDescriptor), + connect.WithClientOptions(opts...), + ), } } @@ -171,6 +182,7 @@ type storeGatewayServiceClient struct { labelNames *connect.Client[v12.LabelNamesRequest, v12.LabelNamesResponse] series *connect.Client[v11.SeriesRequest, v11.SeriesResponse] blockMetadata *connect.Client[v11.BlockMetadataRequest, v11.BlockMetadataResponse] + getBlockStats *connect.Client[v11.GetBlockStatsRequest, v11.GetBlockStatsResponse] } // MergeProfilesStacktraces calls storegateway.v1.StoreGatewayService.MergeProfilesStacktraces. @@ -218,6 +230,11 @@ func (c *storeGatewayServiceClient) BlockMetadata(ctx context.Context, req *conn return c.blockMetadata.CallUnary(ctx, req) } +// GetBlockStats calls storegateway.v1.StoreGatewayService.GetBlockStats. +func (c *storeGatewayServiceClient) GetBlockStats(ctx context.Context, req *connect.Request[v11.GetBlockStatsRequest]) (*connect.Response[v11.GetBlockStatsResponse], error) { + return c.getBlockStats.CallUnary(ctx, req) +} + // StoreGatewayServiceHandler is an implementation of the storegateway.v1.StoreGatewayService // service. type StoreGatewayServiceHandler interface { @@ -232,6 +249,7 @@ type StoreGatewayServiceHandler interface { LabelNames(context.Context, *connect.Request[v12.LabelNamesRequest]) (*connect.Response[v12.LabelNamesResponse], error) Series(context.Context, *connect.Request[v11.SeriesRequest]) (*connect.Response[v11.SeriesResponse], error) BlockMetadata(context.Context, *connect.Request[v11.BlockMetadataRequest]) (*connect.Response[v11.BlockMetadataResponse], error) + GetBlockStats(context.Context, *connect.Request[v11.GetBlockStatsRequest]) (*connect.Response[v11.GetBlockStatsResponse], error) } // NewStoreGatewayServiceHandler builds an HTTP handler from the service implementation. It returns @@ -294,6 +312,12 @@ func NewStoreGatewayServiceHandler(svc StoreGatewayServiceHandler, opts ...conne connect.WithSchema(storeGatewayServiceBlockMetadataMethodDescriptor), connect.WithHandlerOptions(opts...), ) + storeGatewayServiceGetBlockStatsHandler := connect.NewUnaryHandler( + StoreGatewayServiceGetBlockStatsProcedure, + svc.GetBlockStats, + connect.WithSchema(storeGatewayServiceGetBlockStatsMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) return "/storegateway.v1.StoreGatewayService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { case StoreGatewayServiceMergeProfilesStacktracesProcedure: @@ -314,6 +338,8 @@ func NewStoreGatewayServiceHandler(svc StoreGatewayServiceHandler, opts ...conne storeGatewayServiceSeriesHandler.ServeHTTP(w, r) case StoreGatewayServiceBlockMetadataProcedure: storeGatewayServiceBlockMetadataHandler.ServeHTTP(w, r) + case StoreGatewayServiceGetBlockStatsProcedure: + storeGatewayServiceGetBlockStatsHandler.ServeHTTP(w, r) default: http.NotFound(w, r) } @@ -358,3 +384,7 @@ func (UnimplementedStoreGatewayServiceHandler) Series(context.Context, *connect. func (UnimplementedStoreGatewayServiceHandler) BlockMetadata(context.Context, *connect.Request[v11.BlockMetadataRequest]) (*connect.Response[v11.BlockMetadataResponse], error) { return nil, connect.NewError(connect.CodeUnimplemented, errors.New("storegateway.v1.StoreGatewayService.BlockMetadata is not implemented")) } + +func (UnimplementedStoreGatewayServiceHandler) GetBlockStats(context.Context, *connect.Request[v11.GetBlockStatsRequest]) (*connect.Response[v11.GetBlockStatsResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("storegateway.v1.StoreGatewayService.GetBlockStats is not implemented")) +} diff --git a/api/gen/proto/go/storegateway/v1/storegatewayv1connect/storegateway.connect.mux.go b/api/gen/proto/go/storegateway/v1/storegatewayv1connect/storegateway.connect.mux.go index 1c941439cc..0bce6821b9 100644 --- a/api/gen/proto/go/storegateway/v1/storegatewayv1connect/storegateway.connect.mux.go +++ b/api/gen/proto/go/storegateway/v1/storegatewayv1connect/storegateway.connect.mux.go @@ -64,4 +64,9 @@ func RegisterStoreGatewayServiceHandler(mux *mux.Router, svc StoreGatewayService svc.BlockMetadata, opts..., )) + mux.Handle("/storegateway.v1.StoreGatewayService/GetBlockStats", connect.NewUnaryHandler( + "/storegateway.v1.StoreGatewayService/GetBlockStats", + svc.GetBlockStats, + opts..., + )) } diff --git a/api/ingester/v1/ingester.proto b/api/ingester/v1/ingester.proto index b0063fcf76..52bf13600e 100644 --- a/api/ingester/v1/ingester.proto +++ b/api/ingester/v1/ingester.proto @@ -22,6 +22,7 @@ service IngesterService { rpc BlockMetadata(BlockMetadataRequest) returns (BlockMetadataResponse) {} // GetProfileStats returns profile stats for the current tenant. rpc GetProfileStats(types.v1.GetProfileStatsRequest) returns (types.v1.GetProfileStatsResponse) {} + rpc GetBlockStats(GetBlockStatsRequest) returns (GetBlockStatsResponse) {} } message ProfileTypesRequest { @@ -228,3 +229,20 @@ message BlockHints { // When all blocks are compacted, there is no effect of the replication factor, hence we do not need to run deduplication. bool deduplication = 2; } + +message GetBlockStatsRequest { + repeated string ulids = 1; +} + +message GetBlockStatsResponse { + repeated BlockStats block_stats = 1; +} + +message BlockStats { + uint64 series_count = 2; + uint64 profile_count = 3; + uint64 sample_count = 4; + uint64 index_bytes = 5; + uint64 profile_bytes = 6; + uint64 symbol_bytes = 7; +} diff --git a/api/openapiv2/gen/phlare.swagger.json b/api/openapiv2/gen/phlare.swagger.json index b48cd981c2..145f6a2369 100644 --- a/api/openapiv2/gen/phlare.swagger.json +++ b/api/openapiv2/gen/phlare.swagger.json @@ -451,6 +451,23 @@ } } }, + "v1AnalyzeQueryResponse": { + "type": "object", + "properties": { + "queryScopes": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1QueryScope" + }, + "title": "detailed view of what the query will require" + }, + "queryImpact": { + "$ref": "#/definitions/v1QueryImpact", + "title": "summary of the query impact / performance" + } + } + }, "v1BlockCompaction": { "type": "object", "properties": { @@ -527,6 +544,35 @@ } } }, + "v1BlockStats": { + "type": "object", + "properties": { + "seriesCount": { + "type": "string", + "format": "uint64" + }, + "profileCount": { + "type": "string", + "format": "uint64" + }, + "sampleCount": { + "type": "string", + "format": "uint64" + }, + "indexBytes": { + "type": "string", + "format": "uint64" + }, + "profileBytes": { + "type": "string", + "format": "uint64" + }, + "symbolBytes": { + "type": "string", + "format": "uint64" + } + } + }, "v1CommitAuthor": { "type": "object", "properties": { @@ -641,6 +687,18 @@ } } }, + "v1GetBlockStatsResponse": { + "type": "object", + "properties": { + "blockStats": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1BlockStats" + } + } + } + }, "v1GetBuildInfoData": { "type": "object", "properties": { @@ -1050,6 +1108,64 @@ "v1PushResponse": { "type": "object" }, + "v1QueryImpact": { + "type": "object", + "properties": { + "totalBytesInTimeRange": { + "type": "string", + "format": "uint64" + }, + "totalQueriedSeries": { + "type": "string", + "format": "uint64" + }, + "deduplicationNeeded": { + "type": "boolean" + } + } + }, + "v1QueryScope": { + "type": "object", + "properties": { + "componentType": { + "type": "string", + "title": "a descriptive high level name of the component processing one part of the query (e.g., \"short term storage\")" + }, + "componentCount": { + "type": "string", + "format": "uint64", + "title": "how many components of this type will process the query (indicator of read-path replication)" + }, + "blockCount": { + "type": "string", + "format": "uint64" + }, + "seriesCount": { + "type": "string", + "format": "uint64" + }, + "profileCount": { + "type": "string", + "format": "uint64" + }, + "sampleCount": { + "type": "string", + "format": "uint64" + }, + "indexBytes": { + "type": "string", + "format": "uint64" + }, + "profileBytes": { + "type": "string", + "format": "uint64" + }, + "symbolBytes": { + "type": "string", + "format": "uint64" + } + } + }, "v1RawProfileSeries": { "type": "object", "properties": { diff --git a/api/querier/v1/querier.proto b/api/querier/v1/querier.proto index 8a6fca2c9d..3192ecc663 100644 --- a/api/querier/v1/querier.proto +++ b/api/querier/v1/querier.proto @@ -28,6 +28,7 @@ service QuerierService { // GetProfileStats returns profile stats for the current tenant. rpc GetProfileStats(types.v1.GetProfileStatsRequest) returns (types.v1.GetProfileStatsResponse) {} + rpc AnalyzeQuery(AnalyzeQueryRequest) returns (AnalyzeQueryResponse) {} } message ProfileTypesRequest { @@ -150,3 +151,33 @@ message SelectSeriesRequest { message SelectSeriesResponse { repeated types.v1.Series series = 1; } + +message AnalyzeQueryRequest { + int64 start = 2; + int64 end = 3; + string query = 4; +} + +message AnalyzeQueryResponse { + repeated QueryScope query_scopes = 1; // detailed view of what the query will require + QueryImpact query_impact = 2; // summary of the query impact / performance +} + +message QueryScope { + string component_type = 1; // a descriptive high level name of the component processing one part of the query (e.g., "short term storage") + uint64 component_count = 2; // how many components of this type will process the query (indicator of read-path replication) + + uint64 block_count = 3; + uint64 series_count = 4; + uint64 profile_count = 5; + uint64 sample_count = 6; + uint64 index_bytes = 7; + uint64 profile_bytes = 8; + uint64 symbol_bytes = 9; +} + +message QueryImpact { + uint64 total_bytes_in_time_range = 2; + uint64 total_queried_series = 3; + bool deduplication_needed = 4; +} diff --git a/api/storegateway/v1/storegateway.proto b/api/storegateway/v1/storegateway.proto index 102abf9423..c81436659c 100644 --- a/api/storegateway/v1/storegateway.proto +++ b/api/storegateway/v1/storegateway.proto @@ -19,4 +19,5 @@ service StoreGatewayService { rpc LabelNames(types.v1.LabelNamesRequest) returns (types.v1.LabelNamesResponse) {} rpc Series(ingester.v1.SeriesRequest) returns (ingester.v1.SeriesResponse) {} rpc BlockMetadata(ingester.v1.BlockMetadataRequest) returns (ingester.v1.BlockMetadataResponse) {} + rpc GetBlockStats(ingester.v1.GetBlockStatsRequest) returns (ingester.v1.GetBlockStatsResponse) {} } diff --git a/cmd/pyroscope/help-all.txt.tmpl b/cmd/pyroscope/help-all.txt.tmpl index a4ecc98189..0b0c0de789 100644 --- a/cmd/pyroscope/help-all.txt.tmpl +++ b/cmd/pyroscope/help-all.txt.tmpl @@ -551,6 +551,10 @@ Usage of ./pyroscope: Limit how far back in profiling data can be queried, up until lookback duration ago. This limit is enforced in the query frontend. If the requested time range is outside the allowed range, the request will not fail, but will be modified to only query data within the allowed time range. 0 to disable, default to 7d. (default 1w) -querier.max-query-parallelism int Maximum number of queries that will be scheduled in parallel by the frontend. + -querier.query-analysis-enabled + Whether query analysis is enabled in the query frontend. If disabled, the /AnalyzeQuery endpoint will return an empty response. (default true) + -querier.query-analysis-series-enabled + Whether the series portion of query analysis is enabled. If disabled, no series data (e.g., series count) will be calculated by the /AnalyzeQuery endpoint. -querier.query-store-after duration The time after which a metric should be queried from storage and not just ingesters. 0 means all queries are sent to store. If this option is enabled, the time range of the query sent to the store-gateway will be manipulated to ensure the query end is not more recent than 'now - query-store-after'. (default 4h0m0s) -querier.split-queries-by-interval duration diff --git a/cmd/pyroscope/help.txt.tmpl b/cmd/pyroscope/help.txt.tmpl index bcf5fcd771..e949ba0ea2 100644 --- a/cmd/pyroscope/help.txt.tmpl +++ b/cmd/pyroscope/help.txt.tmpl @@ -159,6 +159,10 @@ Usage of ./pyroscope: Limit how far back in profiling data can be queried, up until lookback duration ago. This limit is enforced in the query frontend. If the requested time range is outside the allowed range, the request will not fail, but will be modified to only query data within the allowed time range. 0 to disable, default to 7d. (default 1w) -querier.max-query-parallelism int Maximum number of queries that will be scheduled in parallel by the frontend. + -querier.query-analysis-enabled + Whether query analysis is enabled in the query frontend. If disabled, the /AnalyzeQuery endpoint will return an empty response. (default true) + -querier.query-analysis-series-enabled + Whether the series portion of query analysis is enabled. If disabled, no series data (e.g., series count) will be calculated by the /AnalyzeQuery endpoint. -querier.split-queries-by-interval duration Split queries by a time interval and execute in parallel. The value 0 disables splitting by time -query-scheduler.max-outstanding-requests-per-tenant int diff --git a/docs/sources/configure-server/reference-configuration-parameters/index.md b/docs/sources/configure-server/reference-configuration-parameters/index.md index b81a9c1af5..59748393f6 100644 --- a/docs/sources/configure-server/reference-configuration-parameters/index.md +++ b/docs/sources/configure-server/reference-configuration-parameters/index.md @@ -1883,6 +1883,17 @@ The `limits` block configures default and per-tenant limits imposed by component # CLI flag: -querier.max-query-parallelism [max_query_parallelism: | default = 0] +# Whether query analysis is enabled in the query frontend. If disabled, the +# /AnalyzeQuery endpoint will return an empty response. +# CLI flag: -querier.query-analysis-enabled +[query_analysis_enabled: | default = true] + +# Whether the series portion of query analysis is enabled. If disabled, no +# series data (e.g., series count) will be calculated by the /AnalyzeQuery +# endpoint. +# CLI flag: -querier.query-analysis-series-enabled +[query_analysis_series_enabled: | default = false] + # Maximum number of flame graph nodes by default. 0 to disable. # CLI flag: -querier.max-flamegraph-nodes-default [max_flamegraph_nodes_default: | default = 8192] diff --git a/pkg/frontend/frontend.go b/pkg/frontend/frontend.go index 06498c9f70..6dfb6ad7c1 100644 --- a/pkg/frontend/frontend.go +++ b/pkg/frontend/frontend.go @@ -99,6 +99,7 @@ type Limits interface { MaxQueryParallelism(string) int MaxQueryLength(tenantID string) time.Duration MaxQueryLookback(tenantID string) time.Duration + QueryAnalysisEnabled(string) bool validation.FlameGraphLimits } diff --git a/pkg/frontend/frontend_analyze_query.go b/pkg/frontend/frontend_analyze_query.go new file mode 100644 index 0000000000..531c556747 --- /dev/null +++ b/pkg/frontend/frontend_analyze_query.go @@ -0,0 +1,55 @@ +package frontend + +import ( + "context" + + "connectrpc.com/connect" + "github.com/grafana/dskit/tenant" + "github.com/opentracing/opentracing-go" + "github.com/prometheus/common/model" + + querierv1 "github.com/grafana/pyroscope/api/gen/proto/go/querier/v1" + "github.com/grafana/pyroscope/api/gen/proto/go/querier/v1/querierv1connect" + phlaremodel "github.com/grafana/pyroscope/pkg/model" + "github.com/grafana/pyroscope/pkg/util/connectgrpc" + "github.com/grafana/pyroscope/pkg/validation" +) + +func (f *Frontend) AnalyzeQuery(ctx context.Context, + c *connect.Request[querierv1.AnalyzeQueryRequest]) ( + *connect.Response[querierv1.AnalyzeQueryResponse], error, +) { + opentracing.SpanFromContext(ctx) + + tenantID, err := tenant.TenantID(ctx) + if err != nil { + return nil, connect.NewError(connect.CodeInvalidArgument, err) + } + + if !f.limits.QueryAnalysisEnabled(tenantID) { + return connect.NewResponse(&querierv1.AnalyzeQueryResponse{}), nil + } + + tenantIDs, err := tenant.TenantIDs(ctx) + if err != nil { + return nil, connect.NewError(connect.CodeInvalidArgument, err) + } + + interval, ok := phlaremodel.GetTimeRange(c.Msg) + if ok { + validated, err := validation.ValidateRangeRequest(f.limits, tenantIDs, interval, model.Now()) + if err != nil { + return nil, connect.NewError(connect.CodeInvalidArgument, err) + } + if validated.IsEmpty { + return connect.NewResponse(&querierv1.AnalyzeQueryResponse{}), nil + } + c.Msg.Start = int64(validated.Start) + c.Msg.End = int64(validated.End) + } else { + return connect.NewResponse(&querierv1.AnalyzeQueryResponse{}), nil + } + + ctx = connectgrpc.WithProcedure(ctx, querierv1connect.QuerierServiceAnalyzeQueryProcedure) + return connectgrpc.RoundTripUnary[querierv1.AnalyzeQueryRequest, querierv1.AnalyzeQueryResponse](ctx, f, c) +} diff --git a/pkg/ingester/query.go b/pkg/ingester/query.go index cb03e1c6e1..df188cfe91 100644 --- a/pkg/ingester/query.go +++ b/pkg/ingester/query.go @@ -68,9 +68,14 @@ func (i *Ingester) MergeSpanProfile(ctx context.Context, stream *connect.BidiStr }) } -// GetProfileStats returns func (i *Ingester) GetProfileStats(ctx context.Context, req *connect.Request[typesv1.GetProfileStatsRequest]) (*connect.Response[typesv1.GetProfileStatsResponse], error) { return forInstanceUnary(ctx, i, func(instance *instance) (*connect.Response[typesv1.GetProfileStatsResponse], error) { return instance.GetProfileStats(ctx, req) }) } + +func (i *Ingester) GetBlockStats(ctx context.Context, req *connect.Request[ingestv1.GetBlockStatsRequest]) (*connect.Response[ingestv1.GetBlockStatsResponse], error) { + return forInstanceUnary(ctx, i, func(instance *instance) (*connect.Response[ingestv1.GetBlockStatsResponse], error) { + return instance.GetBlockStats(ctx, req) + }) +} diff --git a/pkg/phlaredb/block/metadata.go b/pkg/phlaredb/block/metadata.go index 32c404edb3..3d9add4c16 100644 --- a/pkg/phlaredb/block/metadata.go +++ b/pkg/phlaredb/block/metadata.go @@ -8,6 +8,7 @@ import ( "math" "os" "path/filepath" + "strings" "time" "github.com/go-kit/log" @@ -20,6 +21,7 @@ import ( "github.com/prometheus/prometheus/tsdb" "github.com/prometheus/prometheus/tsdb/fileutil" + ingestv1 "github.com/grafana/pyroscope/api/gen/proto/go/ingester/v1" typesv1 "github.com/grafana/pyroscope/api/gen/proto/go/types/v1" ) @@ -107,6 +109,17 @@ type BlockDesc struct { MaxTime model.Time `json:"maxTime"` } +type MetaStats struct { + BlockStats + FileStats []FileStats + TotalSizeBytes uint64 +} + +type FileStats struct { + RelPath string + SizeBytes uint64 +} + // BlockMetaCompaction holds information about compactions a block went through. type BlockMetaCompaction struct { // Maximum number of compaction cycles any source block has @@ -328,6 +341,48 @@ func (meta *Meta) TSDBBlockMeta() tsdb.BlockMeta { } } +func (meta *Meta) GetStats() MetaStats { + fileStats := make([]FileStats, 0, len(meta.Files)) + totalSizeBytes := uint64(0) + for _, file := range meta.Files { + fileStats = append(fileStats, FileStats{ + RelPath: file.RelPath, + SizeBytes: file.SizeBytes, + }) + totalSizeBytes += file.SizeBytes + } + + return MetaStats{ + BlockStats: meta.Stats, + FileStats: fileStats, + TotalSizeBytes: totalSizeBytes, + } +} + +func (stats MetaStats) ConvertToBlockStats() *ingestv1.BlockStats { + indexBytes := uint64(0) + profileBytes := uint64(0) + symbolBytes := uint64(0) + for _, f := range stats.FileStats { + if f.RelPath == IndexFilename { + indexBytes = f.SizeBytes + } else if f.RelPath == "profiles.parquet" { + profileBytes += f.SizeBytes + } else if strings.HasPrefix(f.RelPath, "symbols") { + symbolBytes += f.SizeBytes + } + } + blockStats := &ingestv1.BlockStats{ + SeriesCount: stats.NumSeries, + ProfileCount: stats.NumProfiles, + SampleCount: stats.NumSamples, + IndexBytes: indexBytes, + ProfileBytes: profileBytes, + SymbolBytes: symbolBytes, + } + return blockStats +} + // ReadMetaFromDir reads the given meta from /meta.json. func ReadMetaFromDir(dir string) (*Meta, error) { f, err := os.Open(filepath.Join(dir, filepath.Clean(MetaFilename))) diff --git a/pkg/phlaredb/block_querier.go b/pkg/phlaredb/block_querier.go index b333054066..33afa3cf36 100644 --- a/pkg/phlaredb/block_querier.go +++ b/pkg/phlaredb/block_querier.go @@ -547,6 +547,10 @@ func (b *singleBlockQuerier) Bounds() (model.Time, model.Time) { return b.meta.MinTime, b.meta.MaxTime } +func (b *singleBlockQuerier) GetMetaStats() block.MetaStats { + return b.meta.GetStats() +} + type Profile interface { RowNumber() int64 StacktracePartition() uint64 diff --git a/pkg/phlaredb/head.go b/pkg/phlaredb/head.go index 74ecf28d92..b82d5c4904 100644 --- a/pkg/phlaredb/head.go +++ b/pkg/phlaredb/head.go @@ -638,3 +638,9 @@ func (h *Head) updateSymbolsMemUsage(memStats *symdb.MemoryStats) { m.WithLabelValues("mappings").Set(float64(memStats.MappingsSize)) m.WithLabelValues("strings").Set(float64(memStats.StringsSize)) } + +func (h *Head) GetMetaStats() block.MetaStats { + h.metaLock.RLock() + defer h.metaLock.RUnlock() + return h.meta.GetStats() +} diff --git a/pkg/phlaredb/phlaredb.go b/pkg/phlaredb/phlaredb.go index a6d4f81103..a503c7769e 100644 --- a/pkg/phlaredb/phlaredb.go +++ b/pkg/phlaredb/phlaredb.go @@ -8,6 +8,7 @@ import ( "math" "os" "path/filepath" + "slices" "sync" "time" @@ -580,3 +581,32 @@ func getProfileStatsFromBounds(minTimes, maxTimes []model.Time) (*typesv1.GetPro } return response, nil } + +func (f *PhlareDB) GetBlockStats(ctx context.Context, req *connect.Request[ingestv1.GetBlockStatsRequest]) (*connect.Response[ingestv1.GetBlockStatsResponse], error) { + sp, _ := opentracing.StartSpanFromContext(ctx, "PhlareDB GetBlockStats") + defer sp.Finish() + + res := &ingestv1.GetBlockStatsResponse{} + f.headLock.RLock() + for _, h := range f.heads { + if slices.Contains(req.Msg.GetUlids(), h.meta.ULID.String()) { + res.BlockStats = append(res.BlockStats, h.GetMetaStats().ConvertToBlockStats()) + } + } + for _, h := range f.flushing { + if slices.Contains(req.Msg.GetUlids(), h.meta.ULID.String()) { + res.BlockStats = append(res.BlockStats, h.GetMetaStats().ConvertToBlockStats()) + } + } + f.headLock.RUnlock() + + f.blockQuerier.queriersLock.RLock() + for _, q := range f.blockQuerier.queriers { + if slices.Contains(req.Msg.GetUlids(), q.meta.ULID.String()) { + res.BlockStats = append(res.BlockStats, q.GetMetaStats().ConvertToBlockStats()) + } + } + f.blockQuerier.queriersLock.RUnlock() + + return connect.NewResponse(res), nil +} diff --git a/pkg/phlaredb/phlaredb_test.go b/pkg/phlaredb/phlaredb_test.go index 3615b85ffa..b60cb3542b 100644 --- a/pkg/phlaredb/phlaredb_test.go +++ b/pkg/phlaredb/phlaredb_test.go @@ -145,6 +145,10 @@ func (i *ingesterHandlerPhlareDB) GetProfileStats(context.Context, *connect.Requ return nil, errors.New("not implemented") } +func (i *ingesterHandlerPhlareDB) GetBlockStats(context.Context, *connect.Request[ingestv1.GetBlockStatsRequest]) (*connect.Response[ingestv1.GetBlockStatsResponse], error) { + return nil, errors.New("not implemented") +} + func TestMergeProfilesStacktraces(t *testing.T) { defer goleak.VerifyNone(t, goleak.IgnoreCurrent()) diff --git a/pkg/querier/analyze_query.go b/pkg/querier/analyze_query.go new file mode 100644 index 0000000000..67780b2966 --- /dev/null +++ b/pkg/querier/analyze_query.go @@ -0,0 +1,176 @@ +package querier + +import ( + "context" + + "connectrpc.com/connect" + "github.com/grafana/dskit/tenant" + "github.com/opentracing/opentracing-go" + "github.com/prometheus/common/model" + "github.com/prometheus/prometheus/model/labels" + "github.com/prometheus/prometheus/promql/parser" + + ingestv1 "github.com/grafana/pyroscope/api/gen/proto/go/ingester/v1" + querierv1 "github.com/grafana/pyroscope/api/gen/proto/go/querier/v1" + phlaremodel "github.com/grafana/pyroscope/pkg/model" +) + +type queryScope struct { + *querierv1.QueryScope + + blockIds []string +} + +func (q *Querier) AnalyzeQuery(ctx context.Context, req *connect.Request[querierv1.AnalyzeQueryRequest]) (*connect.Response[querierv1.AnalyzeQueryResponse], error) { + sp, ctx := opentracing.StartSpanFromContext(ctx, "AnalyzeQuery") + defer sp.Finish() + + plan, err := q.blockSelect(ctx, model.Time(req.Msg.Start), model.Time(req.Msg.End)) + ingesterQueryScope, storeGatewayQueryScope, deduplicationNeeded := getDataFromPlan(plan) + + blockStatsFromReplicas, err := q.getBlockStatsFromIngesters(ctx, plan, ingesterQueryScope.blockIds) + if err != nil { + return nil, err + } + addBlockStatsToQueryScope(blockStatsFromReplicas, ingesterQueryScope) + + blockStatsFromReplicas, err = q.getBlockStatsFromStoreGateways(ctx, plan, storeGatewayQueryScope.blockIds) + if err != nil { + return nil, err + } + addBlockStatsToQueryScope(blockStatsFromReplicas, storeGatewayQueryScope) + + queriedSeries, err := q.getQueriedSeriesCount(ctx, req.Msg) + if err != nil { + return nil, err + } + + res := createResponse(ingesterQueryScope, storeGatewayQueryScope) + res.QueryImpact.DeduplicationNeeded = deduplicationNeeded + res.QueryImpact.TotalQueriedSeries = queriedSeries + + return connect.NewResponse(res), nil +} + +func getDataFromPlan(plan blockPlan) (ingesterQueryScope *queryScope, storeGatewayQueryScope *queryScope, deduplicationNeeded bool) { + ingesterQueryScope = &queryScope{ + QueryScope: &querierv1.QueryScope{ + ComponentType: "Short term storage", + }, + } + storeGatewayQueryScope = &queryScope{ + QueryScope: &querierv1.QueryScope{ + ComponentType: "Long term storage", + }, + } + deduplicationNeeded = false + for _, planEntry := range plan { + deduplicationNeeded = deduplicationNeeded || planEntry.Deduplication + if planEntry.InstanceType == ingesterInstance { + ingesterQueryScope.ComponentCount += 1 + ingesterQueryScope.BlockCount += uint64(len(planEntry.Ulids)) + ingesterQueryScope.blockIds = append(ingesterQueryScope.blockIds, planEntry.Ulids...) + } else { + storeGatewayQueryScope.ComponentCount += 1 + storeGatewayQueryScope.BlockCount += uint64(len(planEntry.Ulids)) + storeGatewayQueryScope.blockIds = append(storeGatewayQueryScope.blockIds, planEntry.Ulids...) + } + } + return ingesterQueryScope, storeGatewayQueryScope, deduplicationNeeded +} + +func (q *Querier) getBlockStatsFromIngesters(ctx context.Context, plan blockPlan, ingesterBlockIds []string) ([]ResponseFromReplica[*ingestv1.GetBlockStatsResponse], error) { + var blockStatsFromReplicas []ResponseFromReplica[*ingestv1.GetBlockStatsResponse] + blockStatsFromReplicas, err := forAllPlannedIngesters(ctx, q.ingesterQuerier, plan, func(ctx context.Context, iq IngesterQueryClient, hint *ingestv1.Hints) (*ingestv1.GetBlockStatsResponse, error) { + stats, err := iq.GetBlockStats(ctx, connect.NewRequest(&ingestv1.GetBlockStatsRequest{Ulids: ingesterBlockIds})) + if err != nil { + return nil, err + } + return stats.Msg, err + }) + return blockStatsFromReplicas, err +} + +func (q *Querier) getBlockStatsFromStoreGateways(ctx context.Context, plan blockPlan, storeGatewayBlockIds []string) ([]ResponseFromReplica[*ingestv1.GetBlockStatsResponse], error) { + tenantId, err := tenant.TenantID(ctx) + if err != nil { + return nil, err + } + blockStatsFromReplicas, err := forAllPlannedStoreGateways(ctx, tenantId, q.storeGatewayQuerier, plan, func(ctx context.Context, sq StoreGatewayQueryClient, hint *ingestv1.Hints) (*ingestv1.GetBlockStatsResponse, error) { + stats, err := sq.GetBlockStats(ctx, connect.NewRequest(&ingestv1.GetBlockStatsRequest{Ulids: storeGatewayBlockIds})) + if err != nil { + return nil, err + } + return stats.Msg, err + }) + return blockStatsFromReplicas, nil +} + +func addBlockStatsToQueryScope(blockStatsFromReplicas []ResponseFromReplica[*ingestv1.GetBlockStatsResponse], queryScope *queryScope) { + for _, r := range blockStatsFromReplicas { + for _, stats := range r.response.BlockStats { + queryScope.SeriesCount += stats.SeriesCount + queryScope.ProfileCount += stats.ProfileCount + queryScope.SampleCount += stats.SampleCount + queryScope.IndexBytes += stats.IndexBytes + queryScope.ProfileBytes += stats.ProfileBytes + queryScope.SymbolBytes += stats.SymbolBytes + } + } +} + +func (q *Querier) getQueriedSeriesCount(ctx context.Context, req *querierv1.AnalyzeQueryRequest) (uint64, error) { + tenantId, err := tenant.TenantID(ctx) + if err != nil { + return 0, err + } + if !q.limits.QueryAnalysisSeriesEnabled(tenantId) { + return 0, nil + } + matchers, err := createMatchersFromQuery(req.Query) + if err != nil { + return 0, err + } + resSeries, err := q.Series(ctx, connect.NewRequest(&querierv1.SeriesRequest{ + Matchers: matchers, + Start: req.Start, + End: req.End, + })) + if err != nil { + return 0, err + } + return uint64(len(resSeries.Msg.LabelsSet)), nil +} + +func createMatchersFromQuery(query string) ([]string, error) { + var matchers []*labels.Matcher + var err error + if query != "" { + matchers, err = parser.ParseMetricSelector(query) + if err != nil { + return nil, err + } + } + for _, matcher := range matchers { + if matcher.Name == labels.MetricName { + matcher.Name = phlaremodel.LabelNameProfileType + } + } + return []string{convertMatchersToString(matchers)}, nil +} + +func createResponse(ingesterQueryScope *queryScope, storeGatewayQueryScope *queryScope) *querierv1.AnalyzeQueryResponse { + totalBytes := ingesterQueryScope.IndexBytes + + ingesterQueryScope.ProfileBytes + + ingesterQueryScope.SymbolBytes + + storeGatewayQueryScope.IndexBytes + + storeGatewayQueryScope.ProfileBytes + + storeGatewayQueryScope.SymbolBytes + + return &querierv1.AnalyzeQueryResponse{ + QueryScopes: []*querierv1.QueryScope{ingesterQueryScope.QueryScope, storeGatewayQueryScope.QueryScope}, + QueryImpact: &querierv1.QueryImpact{ + TotalBytesInTimeRange: totalBytes, + }, + } +} diff --git a/pkg/querier/analyze_query_test.go b/pkg/querier/analyze_query_test.go new file mode 100644 index 0000000000..62115afeea --- /dev/null +++ b/pkg/querier/analyze_query_test.go @@ -0,0 +1,286 @@ +package querier + +import ( + "slices" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + ingestv1 "github.com/grafana/pyroscope/api/gen/proto/go/ingester/v1" + querierv1 "github.com/grafana/pyroscope/api/gen/proto/go/querier/v1" +) + +func Test_getDataFromPlan(t *testing.T) { + tests := []struct { + name string + plan blockPlan + verifyIngesterQueryScope func(t *testing.T, scope *queryScope) + verifyStoreGatewayQueryScope func(t *testing.T, scope *queryScope) + wantDeduplicationNeeded bool + }{ + { + name: "empty plan", + plan: blockPlan{}, + verifyIngesterQueryScope: func(t *testing.T, scope *queryScope) { + require.Equal(t, &queryScope{ + QueryScope: &querierv1.QueryScope{ + ComponentType: "Short term storage", + }, + }, scope) + }, + verifyStoreGatewayQueryScope: func(t *testing.T, scope *queryScope) { + require.Equal(t, &queryScope{ + QueryScope: &querierv1.QueryScope{ + ComponentType: "Long term storage", + }, + }, scope) + }, + wantDeduplicationNeeded: false, + }, + { + name: "plan with ingesters only", + plan: blockPlan{ + "replica 1": &blockPlanEntry{ + BlockHints: &ingestv1.BlockHints{Ulids: []string{"block A", "block B"}, Deduplication: true}, + InstanceType: ingesterInstance, + }, + "replica 2": &blockPlanEntry{ + BlockHints: &ingestv1.BlockHints{Ulids: []string{"block C", "block D"}, Deduplication: true}, + InstanceType: ingesterInstance, + }, + }, + verifyIngesterQueryScope: func(t *testing.T, scope *queryScope) { + require.Equal(t, uint64(2), scope.ComponentCount) + require.Equal(t, uint64(4), scope.BlockCount) + for _, block := range []string{"block A", "block B", "block C", "block D"} { + require.True(t, slices.Contains(scope.blockIds, block)) + } + }, + verifyStoreGatewayQueryScope: func(t *testing.T, scope *queryScope) { + require.Equal(t, uint64(0), scope.ComponentCount) + }, + wantDeduplicationNeeded: true, + }, + { + name: "plan with ingesters and store gateways", + plan: blockPlan{ + "replica 1": &blockPlanEntry{ + BlockHints: &ingestv1.BlockHints{Ulids: []string{"block A", "block B"}, Deduplication: true}, + InstanceType: ingesterInstance, + }, + "replica 2": &blockPlanEntry{ + BlockHints: &ingestv1.BlockHints{Ulids: []string{"block C", "block D"}, Deduplication: true}, + InstanceType: ingesterInstance, + }, + "replica 3": &blockPlanEntry{ + BlockHints: &ingestv1.BlockHints{Ulids: []string{"block E", "block F"}, Deduplication: true}, + InstanceType: storeGatewayInstance, + }, + }, + verifyIngesterQueryScope: func(t *testing.T, scope *queryScope) { + require.Equal(t, uint64(2), scope.ComponentCount) + require.Equal(t, uint64(4), scope.BlockCount) + for _, block := range []string{"block A", "block B", "block C", "block D"} { + require.True(t, slices.Contains(scope.blockIds, block)) + } + }, + verifyStoreGatewayQueryScope: func(t *testing.T, scope *queryScope) { + require.Equal(t, uint64(1), scope.ComponentCount) + require.Equal(t, uint64(2), scope.BlockCount) + for _, block := range []string{"block E", "block F"} { + require.True(t, slices.Contains(scope.blockIds, block)) + } + }, + wantDeduplicationNeeded: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotIngesterQueryScope, gotStoreGatewayQueryScope, gotDeduplicationNeeded := getDataFromPlan(tt.plan) + tt.verifyIngesterQueryScope(t, gotIngesterQueryScope) + tt.verifyStoreGatewayQueryScope(t, gotStoreGatewayQueryScope) + assert.Equalf(t, tt.wantDeduplicationNeeded, gotDeduplicationNeeded, "getDataFromPlan(%v)", tt.plan) + }) + } +} + +func Test_addBlockStatsToQueryScope(t *testing.T) { + type args struct { + blockStatsFromReplicas []ResponseFromReplica[*ingestv1.GetBlockStatsResponse] + queryScope *queryScope + } + tests := []struct { + name string + args args + verifyExpectations func(t *testing.T, s *queryScope) + }{ + { + name: "with empty block stats", + args: args{ + blockStatsFromReplicas: []ResponseFromReplica[*ingestv1.GetBlockStatsResponse]{}, + queryScope: &queryScope{QueryScope: &querierv1.QueryScope{}}, + }, + verifyExpectations: func(t *testing.T, s *queryScope) { + assert.Equalf(t, uint64(0), s.SeriesCount, "addBlockStatsToQueryScope(%v)", s) + assert.Equalf(t, uint64(0), s.ProfileCount, "addBlockStatsToQueryScope(%v)", s) + assert.Equalf(t, uint64(0), s.SampleCount, "addBlockStatsToQueryScope(%v)", s) + assert.Equalf(t, uint64(0), s.IndexBytes, "addBlockStatsToQueryScope(%v)", s) + assert.Equalf(t, uint64(0), s.ProfileBytes, "addBlockStatsToQueryScope(%v)", s) + assert.Equalf(t, uint64(0), s.SymbolBytes, "addBlockStatsToQueryScope(%v)", s) + }, + }, + { + name: "with valid block stats", + args: args{ + blockStatsFromReplicas: []ResponseFromReplica[*ingestv1.GetBlockStatsResponse]{ + { + addr: "replica 1", + response: &ingestv1.GetBlockStatsResponse{ + BlockStats: []*ingestv1.BlockStats{ + { + SeriesCount: 50, + ProfileCount: 100, + SampleCount: 2000, + IndexBytes: 1024, + ProfileBytes: 4096, + SymbolBytes: 65536, + }, + { + SeriesCount: 100, + ProfileCount: 200, + SampleCount: 4000, + IndexBytes: 2048, + ProfileBytes: 8192, + SymbolBytes: 131072, + }, + }, + }, + }, + { + addr: "replica 2", + response: &ingestv1.GetBlockStatsResponse{ + BlockStats: []*ingestv1.BlockStats{ + { + SeriesCount: 50, + ProfileCount: 100, + SampleCount: 2000, + IndexBytes: 1024, + ProfileBytes: 4096, + SymbolBytes: 65536, + }, + }, + }, + }, + }, + queryScope: &queryScope{QueryScope: &querierv1.QueryScope{}}, + }, + verifyExpectations: func(t *testing.T, s *queryScope) { + assert.Equalf(t, uint64(200), s.SeriesCount, "addBlockStatsToQueryScope(%v)", s) + assert.Equalf(t, uint64(400), s.ProfileCount, "addBlockStatsToQueryScope(%v)", s) + assert.Equalf(t, uint64(8000), s.SampleCount, "addBlockStatsToQueryScope(%v)", s) + assert.Equalf(t, uint64(4096), s.IndexBytes, "addBlockStatsToQueryScope(%v)", s) + assert.Equalf(t, uint64(16384), s.ProfileBytes, "addBlockStatsToQueryScope(%v)", s) + assert.Equalf(t, uint64(262144), s.SymbolBytes, "addBlockStatsToQueryScope(%v)", s) + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + addBlockStatsToQueryScope(tt.args.blockStatsFromReplicas, tt.args.queryScope) + tt.verifyExpectations(t, tt.args.queryScope) + }) + } +} + +func Test_createResponse(t *testing.T) { + type args struct { + ingesterQueryScope *queryScope + storeGatewayQueryScope *queryScope + } + tests := []struct { + name string + args args + want *querierv1.AnalyzeQueryResponse + }{ + { + name: "happy path", + args: args{ + ingesterQueryScope: &queryScope{ + QueryScope: &querierv1.QueryScope{ + IndexBytes: 1024, + ProfileBytes: 2048, + SymbolBytes: 4096, + }, + }, + storeGatewayQueryScope: &queryScope{ + QueryScope: &querierv1.QueryScope{ + IndexBytes: 256, + ProfileBytes: 512, + SymbolBytes: 1024, + }, + }, + }, + want: &querierv1.AnalyzeQueryResponse{ + QueryScopes: []*querierv1.QueryScope{ + { + IndexBytes: 1024, + ProfileBytes: 2048, + SymbolBytes: 4096, + }, + { + IndexBytes: 256, + ProfileBytes: 512, + SymbolBytes: 1024, + }, + }, + QueryImpact: &querierv1.QueryImpact{ + TotalBytesInTimeRange: 8960, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equalf(t, tt.want, createResponse(tt.args.ingesterQueryScope, tt.args.storeGatewayQueryScope), "createResponse(%v, %v)", tt.args.ingesterQueryScope, tt.args.storeGatewayQueryScope) + }) + } +} + +func Test_createMatchersFromQuery(t *testing.T) { + tests := []struct { + name string + query string + want []string + wantErr bool + }{ + { + name: "empty query", + query: "", + want: []string{"{}"}, + wantErr: false, + }, + { + name: "query with a profile type", + query: "process_cpu:cpu:nanoseconds:cpu:nanoseconds{}", + want: []string{"{__profile_type__=\"process_cpu:cpu:nanoseconds:cpu:nanoseconds\"}"}, + wantErr: false, + }, + { + name: "query with labels", + query: "process_cpu:cpu:nanoseconds:cpu:nanoseconds{namespace=\"dev\"}", + want: []string{"{namespace=\"dev\",__profile_type__=\"process_cpu:cpu:nanoseconds:cpu:nanoseconds\"}"}, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := createMatchersFromQuery(tt.query) + if (err != nil) != tt.wantErr { + t.Errorf("Get() error = %v, wantErr %v", err, tt.wantErr) + return + } + assert.Equalf(t, tt.want, got, "createMatchersFromQuery(%v)", tt.query) + }) + } +} diff --git a/pkg/querier/ingester_querier.go b/pkg/querier/ingester_querier.go index aa35bbb3de..ab2a78fc43 100644 --- a/pkg/querier/ingester_querier.go +++ b/pkg/querier/ingester_querier.go @@ -2,7 +2,6 @@ package querier import ( "context" - "fmt" "connectrpc.com/connect" "github.com/grafana/dskit/ring" @@ -33,6 +32,7 @@ type IngesterQueryClient interface { MergeSpanProfile(ctx context.Context) clientpool.BidiClientMergeSpanProfile BlockMetadata(ctx context.Context, req *connect.Request[ingestv1.BlockMetadataRequest]) (*connect.Response[ingestv1.BlockMetadataResponse], error) GetProfileStats(ctx context.Context, req *connect.Request[typesv1.GetProfileStatsRequest]) (*connect.Response[typesv1.GetProfileStatsResponse], error) + GetBlockStats(ctx context.Context, req *connect.Request[ingestv1.GetBlockStatsRequest]) (*connect.Response[ingestv1.GetBlockStatsResponse], error) } // IngesterQuerier helps with querying the ingesters. @@ -114,9 +114,9 @@ func (q *Querier) selectTreeFromIngesters(ctx context.Context, req *querierv1.Se g, gCtx := errgroup.WithContext(ctx) for idx := range responses { r := responses[idx] - hints, ok := plan[r.addr] - if !ok && plan != nil { - return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("no hints found for replica %s", r.addr)) + blockHints, err := BlockHints(plan, r.addr) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) } g.Go(util.RecoverPanic(func() error { @@ -126,7 +126,7 @@ func (q *Querier) selectTreeFromIngesters(ctx context.Context, req *querierv1.Se Start: req.Start, End: req.End, Type: profileType, - Hints: &ingestv1.Hints{Block: hints}, + Hints: &ingestv1.Hints{Block: blockHints}, }, MaxNodes: req.MaxNodes, }) @@ -171,9 +171,9 @@ func (q *Querier) selectProfileFromIngesters(ctx context.Context, req *querierv1 g, gCtx := errgroup.WithContext(ctx) for idx := range responses { r := responses[idx] - hints, ok := plan[r.addr] - if !ok && plan != nil { - return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("no hints found for replica %s", r.addr)) + blockHints, err := BlockHints(plan, r.addr) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) } g.Go(util.RecoverPanic(func() error { @@ -183,7 +183,7 @@ func (q *Querier) selectProfileFromIngesters(ctx context.Context, req *querierv1 Start: req.Start, End: req.End, Type: profileType, - Hints: &ingestv1.Hints{Block: hints}, + Hints: &ingestv1.Hints{Block: blockHints}, }, MaxNodes: req.MaxNodes, StackTraceSelector: req.StackTraceSelector, @@ -199,7 +199,7 @@ func (q *Querier) selectProfileFromIngesters(ctx context.Context, req *querierv1 return selectMergePprofProfile(gCtx, profileType, responses) } -func (q *Querier) selectSeriesFromIngesters(ctx context.Context, req *ingesterv1.MergeProfilesLabelsRequest, plan map[string]*ingestv1.BlockHints) ([]ResponseFromReplica[clientpool.BidiClientMergeProfilesLabels], error) { +func (q *Querier) selectSeriesFromIngesters(ctx context.Context, req *ingesterv1.MergeProfilesLabelsRequest, plan map[string]*blockPlanEntry) ([]ResponseFromReplica[clientpool.BidiClientMergeProfilesLabels], error) { sp, ctx := opentracing.StartSpanFromContext(ctx, "SelectSeries Ingesters") defer sp.Finish() var responses []ResponseFromReplica[clientpool.BidiClientMergeProfilesLabels] @@ -221,13 +221,13 @@ func (q *Querier) selectSeriesFromIngesters(ctx context.Context, req *ingesterv1 g, _ := errgroup.WithContext(ctx) for _, r := range responses { r := r - hints, ok := plan[r.addr] - if !ok && plan != nil { - return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("no hints found for replica %s", r.addr)) + blockHints, err := BlockHints(plan, r.addr) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) } g.Go(util.RecoverPanic(func() error { req := req.CloneVT() - req.Request.Hints = &ingestv1.Hints{Block: hints} + req.Request.Hints = &ingestv1.Hints{Block: blockHints} return r.response.Send(req) })) } @@ -293,7 +293,7 @@ func (q *Querier) seriesFromIngesters(ctx context.Context, req *ingesterv1.Serie return responses, nil } -func (q *Querier) selectSpanProfileFromIngesters(ctx context.Context, req *querierv1.SelectMergeSpanProfileRequest, plan map[string]*ingestv1.BlockHints) (*phlaremodel.Tree, error) { +func (q *Querier) selectSpanProfileFromIngesters(ctx context.Context, req *querierv1.SelectMergeSpanProfileRequest, plan map[string]*blockPlanEntry) (*phlaremodel.Tree, error) { sp, ctx := opentracing.StartSpanFromContext(ctx, "SelectMergeSpanProfile Ingesters") defer sp.Finish() profileType, err := phlaremodel.ParseProfileTypeSelector(req.ProfileTypeID) @@ -324,9 +324,9 @@ func (q *Querier) selectSpanProfileFromIngesters(ctx context.Context, req *queri g, gCtx := errgroup.WithContext(ctx) for idx := range responses { r := responses[idx] - hints, ok := plan[r.addr] - if !ok && plan != nil { - return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("no hints found for replica %s", r.addr)) + blockHints, err := BlockHints(plan, r.addr) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) } g.Go(util.RecoverPanic(func() error { @@ -337,7 +337,7 @@ func (q *Querier) selectSpanProfileFromIngesters(ctx context.Context, req *queri End: req.End, Type: profileType, SpanSelector: req.SpanSelector, - Hints: &ingestv1.Hints{Block: hints}, + Hints: &ingestv1.Hints{Block: blockHints}, }, MaxNodes: req.MaxNodes, }) diff --git a/pkg/querier/querier.go b/pkg/querier/querier.go index 1ebf7025d9..2012b078ea 100644 --- a/pkg/querier/querier.go +++ b/pkg/querier/querier.go @@ -56,6 +56,10 @@ func (cfg *Config) RegisterFlags(fs *flag.FlagSet) { fs.DurationVar(&cfg.QueryStoreAfter, "querier.query-store-after", 4*time.Hour, "The time after which a metric should be queried from storage and not just ingesters. 0 means all queries are sent to store. If this option is enabled, the time range of the query sent to the store-gateway will be manipulated to ensure the query end is not more recent than 'now - query-store-after'.") } +type Limits interface { + QueryAnalysisSeriesEnabled(string) bool +} + type Querier struct { services.Service subservices *services.Manager @@ -71,6 +75,8 @@ type Querier struct { storageBucket phlareobj.Bucket tenantConfigProvider phlareobj.TenantConfigProvider + + limits Limits } // TODO(kolesnikovae): For backwards compatibility. @@ -128,6 +134,7 @@ func New(params *NewQuerierParams) (*Querier, error) { VCSServiceHandler: vcs.New(params.Logger), storageBucket: params.StorageBucket, tenantConfigProvider: params.CfgProvider, + limits: params.Overrides, } svcs := []services.Service{q.ingesterQuerier.pool} @@ -354,7 +361,7 @@ func (q *Querier) blockSelect(ctx context.Context, start, end model.Time) (block results := newReplicasPerBlockID(q.logger) - // get first all blocks from store gateways, as they should be querier with a priority and also aret the only ones containing duplicated blocks because of replication + // get first all blocks from store gateways, as they should be querier with a priority and also are the only ones containing duplicated blocks because of replication if q.storeGatewayQuerier != nil { res, err := q.blockSelectFromStoreGateway(ctx, ingesterReq) if err != nil { @@ -963,7 +970,7 @@ func (q *Querier) SelectSeries(ctx context.Context, req *connect.Request[querier }), nil } -func (q *Querier) selectSeries(ctx context.Context, req *connect.Request[querierv1.SelectSeriesRequest], plan map[string]*ingestv1.BlockHints) ([]ResponseFromReplica[clientpool.BidiClientMergeProfilesLabels], error) { +func (q *Querier) selectSeries(ctx context.Context, req *connect.Request[querierv1.SelectSeriesRequest], plan map[string]*blockPlanEntry) ([]ResponseFromReplica[clientpool.BidiClientMergeProfilesLabels], error) { stepMs := time.Duration(req.Msg.Step * float64(time.Second)).Milliseconds() sort.Strings(req.Msg.GroupBy) diff --git a/pkg/querier/querier_test.go b/pkg/querier/querier_test.go index 5aed2e56e3..bc71906b80 100644 --- a/pkg/querier/querier_test.go +++ b/pkg/querier/querier_test.go @@ -748,6 +748,22 @@ func (f *fakeQuerierIngester) GetProfileStats(ctx context.Context, req *connect. return res, err } +func (f *fakeQuerierIngester) GetBlockStats(ctx context.Context, req *connect.Request[ingestv1.GetBlockStatsRequest]) (*connect.Response[ingestv1.GetBlockStatsResponse], error) { + var ( + args = f.Called(ctx, req) + res *connect.Response[ingestv1.GetBlockStatsResponse] + err error + ) + if args[0] != nil { + res = args[0].(*connect.Response[ingestv1.GetBlockStatsResponse]) + } + if args[1] != nil { + err = args.Get(1).(error) + } + + return res, err +} + type testProfile struct { Ts int64 Labels *typesv1.Labels @@ -1334,7 +1350,7 @@ func Test_splitQueryToStores(t *testing.T) { start: model.TimeFromUnixNano(int64(30 * time.Minute)), end: model.TimeFromUnixNano(int64(45*time.Minute) + int64(3*time.Hour)), queryStoreAfter: 30 * time.Minute, - plan: blockPlan{"replica-a": &ingestv1.BlockHints{Ulids: []string{"block-a", "block-b"}}}, + plan: blockPlan{"replica-a": &blockPlanEntry{InstanceType: ingesterInstance, BlockHints: &ingestv1.BlockHints{Ulids: []string{"block-a", "block-b"}}}}, expected: storeQueries{ queryStoreAfter: 0, diff --git a/pkg/querier/replication.go b/pkg/querier/replication.go index 2969c9ee0e..1e772d6e91 100644 --- a/pkg/querier/replication.go +++ b/pkg/querier/replication.go @@ -89,7 +89,7 @@ func forGivenReplicationSet[Result any, Querier any](ctx context.Context, client } // forGivenPlan runs f, in parallel, for given plan. -func forGivenPlan[Result any, Querier any](ctx context.Context, plan map[string]*ingestv1.BlockHints, clientFactory func(string) (Querier, error), replicationSet ring.ReplicationSet, f QueryReplicaWithHintsFn[Result, Querier]) ([]ResponseFromReplica[Result], error) { +func forGivenPlan[Result any, Querier any](ctx context.Context, plan map[string]*blockPlanEntry, clientFactory func(string) (Querier, error), replicationSet ring.ReplicationSet, f QueryReplicaWithHintsFn[Result, Querier]) ([]ResponseFromReplica[Result], error) { g, _ := errgroup.WithContext(ctx) var ( @@ -97,14 +97,14 @@ func forGivenPlan[Result any, Querier any](ctx context.Context, plan map[string] result = make([]ResponseFromReplica[Result], len(plan)) ) - for replica, hints := range plan { + for replica, planEntry := range plan { if !replicationSet.Includes(replica) { continue } var ( i = idx r = replica - h = hints + h = planEntry.BlockHints ) idx++ g.Go(func() error { @@ -320,21 +320,37 @@ func (r *replicasPerBlockID) pruneSupersededBlocks(sharded bool) error { return nil } -type blockPlan map[string]*ingestv1.BlockHints +type blockPlanEntry struct { + *ingestv1.BlockHints + InstanceType instanceType +} + +type blockPlan map[string]*blockPlanEntry + +func BlockHints(p blockPlan, replica string) (*ingestv1.BlockHints, error) { + entry, ok := p[replica] + if !ok && p != nil { + return nil, fmt.Errorf("no hints found for replica %s", replica) + } + if entry == nil { + return nil, nil + } + return entry.BlockHints, nil +} func (p blockPlan) String() string { data, _ := json.Marshal(p) return string(data) } -func (r *replicasPerBlockID) blockPlan(ctx context.Context) map[string]*ingestv1.BlockHints { +func (r *replicasPerBlockID) blockPlan(ctx context.Context) map[string]*blockPlanEntry { sp, _ := opentracing.StartSpanFromContext(ctx, "blockPlan") defer sp.Finish() var ( deduplicate = false hash = xxhash.New() - plan = make(map[string]*ingestv1.BlockHints) + plan = make(map[string]*blockPlanEntry) smallestCompactionLevel = int32(0) ) @@ -406,7 +422,10 @@ func (r *replicasPerBlockID) blockPlan(ctx context.Context) map[string]*ingestv1 // add block to plan p, exists := plan[selectedReplica] if !exists { - p = &ingestv1.BlockHints{} + p = &blockPlanEntry{ + BlockHints: &ingestv1.BlockHints{}, + InstanceType: r.instanceType[selectedReplica], + } plan[selectedReplica] = p } p.Ulids = append(p.Ulids, blockID) @@ -422,14 +441,14 @@ func (r *replicasPerBlockID) blockPlan(ctx context.Context) map[string]*ingestv1 } } - var plannedIngesterBlocks, plannedStoreGatwayBlocks int + var plannedIngesterBlocks, plannedStoreGatewayBlocks int for replica, blocks := range plan { t, ok := r.instanceType[replica] if !ok { continue } if t == storeGatewayInstance { - plannedStoreGatwayBlocks += len(blocks.Ulids) + plannedStoreGatewayBlocks += len(blocks.Ulids) } if t == ingesterInstance { plannedIngesterBlocks += len(blocks.Ulids) @@ -440,7 +459,7 @@ func (r *replicasPerBlockID) blockPlan(ctx context.Context) map[string]*ingestv1 otlog.Bool("deduplicate", deduplicate), otlog.Int32("smallest_compaction_level", smallestCompactionLevel), otlog.Int("planned_blocks_ingesters", plannedIngesterBlocks), - otlog.Int("planned_blocks_store_gateways", plannedStoreGatwayBlocks), + otlog.Int("planned_blocks_store_gateways", plannedStoreGatewayBlocks), ) level.Debug(spanlogger.FromContext(ctx, r.logger)).Log( @@ -448,7 +467,7 @@ func (r *replicasPerBlockID) blockPlan(ctx context.Context) map[string]*ingestv1 "deduplicate", deduplicate, "smallest_compaction_level", smallestCompactionLevel, "planned_blocks_ingesters", plannedIngesterBlocks, - "planned_blocks_store_gateways", plannedStoreGatwayBlocks, + "planned_blocks_store_gateways", plannedStoreGatewayBlocks, "plan", blockPlan(plan), ) diff --git a/pkg/querier/replication_test.go b/pkg/querier/replication_test.go index 79abd2b2d1..ea452181ca 100644 --- a/pkg/querier/replication_test.go +++ b/pkg/querier/replication_test.go @@ -11,7 +11,6 @@ import ( "github.com/prometheus/common/model" "github.com/stretchr/testify/require" - ingestv1 "github.com/grafana/pyroscope/api/gen/proto/go/ingester/v1" typesv1 "github.com/grafana/pyroscope/api/gen/proto/go/types/v1" "github.com/grafana/pyroscope/pkg/phlaredb/sharding" ) @@ -71,13 +70,13 @@ func (b *blockInfo) info() *typesv1.BlockInfo { return &b.i } -type validatorFunc func(t *testing.T, plan map[string]*ingestv1.BlockHints) +type validatorFunc func(t *testing.T, plan map[string]*blockPlanEntry) func validatePlanBlockIDs(expBlockIDs ...string) validatorFunc { - return func(t *testing.T, plan map[string]*ingestv1.BlockHints) { + return func(t *testing.T, plan map[string]*blockPlanEntry) { var blockIDs []string - for _, hints := range plan { - blockIDs = append(blockIDs, hints.Ulids...) + for _, planEntry := range plan { + blockIDs = append(blockIDs, planEntry.Ulids...) } sort.Strings(blockIDs) require.Equal(t, expBlockIDs, blockIDs) @@ -85,11 +84,11 @@ func validatePlanBlockIDs(expBlockIDs ...string) validatorFunc { } func validatePlanBlocksOnReplica(replica string, blocks ...string) validatorFunc { - return func(t *testing.T, plan map[string]*ingestv1.BlockHints) { - blockHints, ok := plan[replica] + return func(t *testing.T, plan map[string]*blockPlanEntry) { + planEntry, ok := plan[replica] require.True(t, ok, fmt.Sprintf("replica %s not found in plan", replica)) for _, block := range blocks { - require.Contains(t, blockHints.Ulids, block, "block %s not found in replica's %s plan", block, replica) + require.Contains(t, planEntry.Ulids, block, "block %s not found in replica's %s plan", block, replica) } } } diff --git a/pkg/querier/store_gateway_querier.go b/pkg/querier/store_gateway_querier.go index 1e7f4cb1fc..6a53350980 100644 --- a/pkg/querier/store_gateway_querier.go +++ b/pkg/querier/store_gateway_querier.go @@ -2,7 +2,6 @@ package querier import ( "context" - "fmt" "connectrpc.com/connect" "github.com/go-kit/log" @@ -39,6 +38,7 @@ type StoreGatewayQueryClient interface { LabelNames(context.Context, *connect.Request[typesv1.LabelNamesRequest]) (*connect.Response[typesv1.LabelNamesResponse], error) Series(context.Context, *connect.Request[ingestv1.SeriesRequest]) (*connect.Response[ingestv1.SeriesResponse], error) BlockMetadata(ctx context.Context, req *connect.Request[ingestv1.BlockMetadataRequest]) (*connect.Response[ingestv1.BlockMetadataResponse], error) + GetBlockStats(ctx context.Context, req *connect.Request[ingestv1.GetBlockStatsRequest]) (*connect.Response[ingestv1.GetBlockStatsResponse], error) } type StoreGatewayLimits interface { @@ -145,7 +145,7 @@ func forAllStoreGateways[T any](ctx context.Context, tenantID string, storegatew } // forAllPlannedStoreGatway runs f, in parallel, for all store-gateways part of the plan -func forAllPlannedStoreGateways[T any](ctx context.Context, _ string, storegatewayQuerier *StoreGatewayQuerier, plan map[string]*ingestv1.BlockHints, f QueryReplicaWithHintsFn[T, StoreGatewayQueryClient]) ([]ResponseFromReplica[T], error) { +func forAllPlannedStoreGateways[T any](ctx context.Context, _ string, storegatewayQuerier *StoreGatewayQuerier, plan map[string]*blockPlanEntry, f QueryReplicaWithHintsFn[T, StoreGatewayQueryClient]) ([]ResponseFromReplica[T], error) { replicationSet, err := storegatewayQuerier.ring.GetReplicationSetForOperation(readNoExtend) if err != nil { return nil, err @@ -174,7 +174,7 @@ func GetShuffleShardingSubring(ring ring.ReadRing, userID string, limits StoreGa return ring.ShuffleShard(userID, shardSize) } -func (q *Querier) selectTreeFromStoreGateway(ctx context.Context, req *querierv1.SelectMergeStacktracesRequest, plan map[string]*ingestv1.BlockHints) (*phlaremodel.Tree, error) { +func (q *Querier) selectTreeFromStoreGateway(ctx context.Context, req *querierv1.SelectMergeStacktracesRequest, plan map[string]*blockPlanEntry) (*phlaremodel.Tree, error) { sp, ctx := opentracing.StartSpanFromContext(ctx, "SelectTree StoreGateway") defer sp.Finish() profileType, err := phlaremodel.ParseProfileTypeSelector(req.ProfileTypeID) @@ -209,9 +209,9 @@ func (q *Querier) selectTreeFromStoreGateway(ctx context.Context, req *querierv1 g, gCtx := errgroup.WithContext(ctx) for _, r := range responses { r := r - hints, ok := plan[r.addr] - if !ok && plan != nil { - return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("no hints found for replica %s", r.addr)) + blockHints, err := BlockHints(plan, r.addr) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) } g.Go(util.RecoverPanic(func() error { return r.response.Send(&ingestv1.MergeProfilesStacktracesRequest{ @@ -220,7 +220,7 @@ func (q *Querier) selectTreeFromStoreGateway(ctx context.Context, req *querierv1 Start: req.Start, End: req.End, Type: profileType, - Hints: &ingestv1.Hints{Block: hints}, + Hints: &ingestv1.Hints{Block: blockHints}, }, MaxNodes: req.MaxNodes, }) @@ -234,7 +234,7 @@ func (q *Querier) selectTreeFromStoreGateway(ctx context.Context, req *querierv1 return selectMergeTree(gCtx, responses) } -func (q *Querier) selectProfileFromStoreGateway(ctx context.Context, req *querierv1.SelectMergeProfileRequest, plan map[string]*ingestv1.BlockHints) (*googlev1.Profile, error) { +func (q *Querier) selectProfileFromStoreGateway(ctx context.Context, req *querierv1.SelectMergeProfileRequest, plan map[string]*blockPlanEntry) (*googlev1.Profile, error) { sp, ctx := opentracing.StartSpanFromContext(ctx, "SelectProfile StoreGateway") defer sp.Finish() profileType, err := phlaremodel.ParseProfileTypeSelector(req.ProfileTypeID) @@ -269,9 +269,9 @@ func (q *Querier) selectProfileFromStoreGateway(ctx context.Context, req *querie g, gCtx := errgroup.WithContext(ctx) for _, r := range responses { r := r - hints, ok := plan[r.addr] - if !ok && plan != nil { - return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("no hints found for replica %s", r.addr)) + blockHints, err := BlockHints(plan, r.addr) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) } g.Go(util.RecoverPanic(func() error { return r.response.Send(&ingestv1.MergeProfilesPprofRequest{ @@ -280,7 +280,7 @@ func (q *Querier) selectProfileFromStoreGateway(ctx context.Context, req *querie Start: req.Start, End: req.End, Type: profileType, - Hints: &ingestv1.Hints{Block: hints}, + Hints: &ingestv1.Hints{Block: blockHints}, }, MaxNodes: req.MaxNodes, StackTraceSelector: req.StackTraceSelector, @@ -295,7 +295,7 @@ func (q *Querier) selectProfileFromStoreGateway(ctx context.Context, req *querie return selectMergePprofProfile(gCtx, profileType, responses) } -func (q *Querier) selectSeriesFromStoreGateway(ctx context.Context, req *ingesterv1.MergeProfilesLabelsRequest, plan map[string]*ingestv1.BlockHints) ([]ResponseFromReplica[clientpool.BidiClientMergeProfilesLabels], error) { +func (q *Querier) selectSeriesFromStoreGateway(ctx context.Context, req *ingesterv1.MergeProfilesLabelsRequest, plan map[string]*blockPlanEntry) ([]ResponseFromReplica[clientpool.BidiClientMergeProfilesLabels], error) { sp, ctx := opentracing.StartSpanFromContext(ctx, "SelectSeries StoreGateway") defer sp.Finish() tenantID, err := tenant.ExtractTenantIDFromContext(ctx) @@ -320,13 +320,13 @@ func (q *Querier) selectSeriesFromStoreGateway(ctx context.Context, req *ingeste g, _ := errgroup.WithContext(ctx) for _, r := range responses { r := r - hints, ok := plan[r.addr] - if !ok && plan != nil { - return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("no hints found for replica %s", r.addr)) + blockHints, err := BlockHints(plan, r.addr) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) } g.Go(util.RecoverPanic(func() error { req := req.CloneVT() - req.Request.Hints = &ingestv1.Hints{Block: hints} + req.Request.Hints = &ingestv1.Hints{Block: blockHints} return r.response.Send(req) })) } @@ -402,7 +402,7 @@ func (q *Querier) seriesFromStoreGateway(ctx context.Context, req *ingestv1.Seri return responses, nil } -func (q *Querier) selectSpanProfileFromStoreGateway(ctx context.Context, req *querierv1.SelectMergeSpanProfileRequest, plan map[string]*ingestv1.BlockHints) (*phlaremodel.Tree, error) { +func (q *Querier) selectSpanProfileFromStoreGateway(ctx context.Context, req *querierv1.SelectMergeSpanProfileRequest, plan map[string]*blockPlanEntry) (*phlaremodel.Tree, error) { sp, ctx := opentracing.StartSpanFromContext(ctx, "SelectSpanProfile StoreGateway") defer sp.Finish() profileType, err := phlaremodel.ParseProfileTypeSelector(req.ProfileTypeID) @@ -437,9 +437,9 @@ func (q *Querier) selectSpanProfileFromStoreGateway(ctx context.Context, req *qu g, gCtx := errgroup.WithContext(ctx) for _, r := range responses { r := r - hints, ok := plan[r.addr] - if !ok && plan != nil { - return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("no hints found for replica %s", r.addr)) + blockHints, err := BlockHints(plan, r.addr) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) } g.Go(util.RecoverPanic(func() error { return r.response.Send(&ingestv1.MergeSpanProfileRequest{ @@ -449,7 +449,7 @@ func (q *Querier) selectSpanProfileFromStoreGateway(ctx context.Context, req *qu End: req.End, Type: profileType, SpanSelector: req.SpanSelector, - Hints: &ingestv1.Hints{Block: hints}, + Hints: &ingestv1.Hints{Block: blockHints}, }, MaxNodes: req.MaxNodes, }) diff --git a/pkg/storegateway/query.go b/pkg/storegateway/query.go index aa166f7145..ded9dcf4a3 100644 --- a/pkg/storegateway/query.go +++ b/pkg/storegateway/query.go @@ -3,6 +3,7 @@ package storegateway import ( "context" "io" + "slices" "connectrpc.com/connect" "github.com/pkg/errors" @@ -140,6 +141,25 @@ func (s *StoreGateway) BlockMetadata(ctx context.Context, req *connect.Request[i return connect.NewResponse(res), nil } +func (s *StoreGateway) GetBlockStats(ctx context.Context, req *connect.Request[ingestv1.GetBlockStatsRequest]) (*connect.Response[ingestv1.GetBlockStatsResponse], error) { + res := &ingestv1.GetBlockStatsResponse{} + _, err := s.forBucketStore(ctx, func(bs *BucketStore) error { + bs.blocksMx.RLock() + defer bs.blocksMx.RUnlock() + + for ulid, block := range bs.blocks { + if slices.Contains(req.Msg.Ulids, ulid.String()) { + res.BlockStats = append(res.BlockStats, block.meta.GetStats().ConvertToBlockStats()) + } + } + return nil + }) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + return connect.NewResponse(res), nil +} + func terminateStream[Req, Resp any](stream *connect.BidiStream[Req, Resp]) (err error) { if _, err = stream.Receive(); err != nil { if errors.Is(err, io.EOF) { diff --git a/pkg/validation/limits.go b/pkg/validation/limits.go index 1b269963b4..64a9fd91b6 100644 --- a/pkg/validation/limits.go +++ b/pkg/validation/limits.go @@ -55,9 +55,11 @@ type Limits struct { MaxGlobalSeriesPerTenant int `yaml:"max_global_series_per_tenant" json:"max_global_series_per_tenant"` // Querier enforced limits. - MaxQueryLookback model.Duration `yaml:"max_query_lookback" json:"max_query_lookback"` - MaxQueryLength model.Duration `yaml:"max_query_length" json:"max_query_length"` - MaxQueryParallelism int `yaml:"max_query_parallelism" json:"max_query_parallelism"` + MaxQueryLookback model.Duration `yaml:"max_query_lookback" json:"max_query_lookback"` + MaxQueryLength model.Duration `yaml:"max_query_length" json:"max_query_length"` + MaxQueryParallelism int `yaml:"max_query_parallelism" json:"max_query_parallelism"` + QueryAnalysisEnabled bool `yaml:"query_analysis_enabled" json:"query_analysis_enabled"` + QueryAnalysisSeriesEnabled bool `yaml:"query_analysis_series_enabled" json:"query_analysis_series_enabled"` // Flame graph enforced limits. MaxFlameGraphNodesDefault int `yaml:"max_flamegraph_nodes_default" json:"max_flamegraph_nodes_default"` @@ -124,6 +126,9 @@ func (l *Limits) RegisterFlags(f *flag.FlagSet) { f.IntVar(&l.MaxQueryParallelism, "querier.max-query-parallelism", 0, "Maximum number of queries that will be scheduled in parallel by the frontend.") + f.BoolVar(&l.QueryAnalysisEnabled, "querier.query-analysis-enabled", true, "Whether query analysis is enabled in the query frontend. If disabled, the /AnalyzeQuery endpoint will return an empty response.") + f.BoolVar(&l.QueryAnalysisSeriesEnabled, "querier.query-analysis-series-enabled", false, "Whether the series portion of query analysis is enabled. If disabled, no series data (e.g., series count) will be calculated by the /AnalyzeQuery endpoint.") + f.IntVar(&l.MaxProfileSizeBytes, "validation.max-profile-size-bytes", 4*1024*1024, "Maximum size of a profile in bytes. This is based off the uncompressed size. 0 to disable.") f.IntVar(&l.MaxProfileStacktraceSamples, "validation.max-profile-stacktrace-samples", 16000, "Maximum number of samples in a profile. 0 to disable.") f.IntVar(&l.MaxProfileStacktraceSampleLabels, "validation.max-profile-stacktrace-sample-labels", 100, "Maximum number of labels in a profile sample. 0 to disable.") @@ -411,6 +416,17 @@ func (o *Overrides) RejectOlderThan(tenantID string) time.Duration { return time.Duration(o.getOverridesForTenant(tenantID).RejectOlderThan) } +// QueryAnalysisEnabled can be used to disable the query analysis endpoint in the query frontend. +func (o *Overrides) QueryAnalysisEnabled(tenantID string) bool { + return o.getOverridesForTenant(tenantID).QueryAnalysisEnabled +} + +// QueryAnalysisSeriesEnabled can be used to disable the series portion of the query analysis endpoint in the query frontend. +// To be used for tenants where calculating series can be expensive. +func (o *Overrides) QueryAnalysisSeriesEnabled(tenantID string) bool { + return o.getOverridesForTenant(tenantID).QueryAnalysisSeriesEnabled +} + func (o *Overrides) DefaultLimits() *Limits { return o.defaultLimits } diff --git a/pkg/validation/testutil.go b/pkg/validation/testutil.go index 18b7d1d52c..13e04f9a06 100644 --- a/pkg/validation/testutil.go +++ b/pkg/validation/testutil.go @@ -5,13 +5,15 @@ import ( ) type MockLimits struct { - QuerySplitDurationValue time.Duration - MaxQueryParallelismValue int - MaxQueryLengthValue time.Duration - MaxQueryLookbackValue time.Duration - MaxLabelNameLengthValue int - MaxLabelValueLengthValue int - MaxLabelNamesPerSeriesValue int + QuerySplitDurationValue time.Duration + MaxQueryParallelismValue int + MaxQueryLengthValue time.Duration + MaxQueryLookbackValue time.Duration + QueryAnalysisEnabledValue bool + QueryAnalysisSeriesEnabledValue bool + MaxLabelNameLengthValue int + MaxLabelValueLengthValue int + MaxLabelNamesPerSeriesValue int MaxFlameGraphNodesDefaultValue int MaxFlameGraphNodesMaxValue int @@ -33,6 +35,10 @@ func (m MockLimits) QuerySplitDuration(string) time.Duration { return m.Q func (m MockLimits) MaxQueryParallelism(string) int { return m.MaxQueryParallelismValue } func (m MockLimits) MaxQueryLength(tenantID string) time.Duration { return m.MaxQueryLengthValue } func (m MockLimits) MaxQueryLookback(tenantID string) time.Duration { return m.MaxQueryLookbackValue } +func (m MockLimits) QueryAnalysisEnabled(tenantID string) bool { return m.QueryAnalysisEnabledValue } +func (m MockLimits) QueryAnalysisSeriesEnabled(tenantID string) bool { + return m.QueryAnalysisSeriesEnabledValue +} func (m MockLimits) MaxFlameGraphNodesDefault(string) int { return m.MaxFlameGraphNodesDefaultValue } func (m MockLimits) MaxFlameGraphNodesMax(string) int { return m.MaxFlameGraphNodesMaxValue }