diff --git a/backend/controller/console/console.go b/backend/controller/console/console.go index 2de3026166..53e2165731 100644 --- a/backend/controller/console/console.go +++ b/backend/controller/console/console.go @@ -358,6 +358,12 @@ func eventsQueryProtoToDAL(pb *pbconsole.EventsQuery) ([]timeline.TimelineFilter destVerb = optional.Some(*filter.Call.DestVerb) } query = append(query, timeline.FilterCall(sourceModule, filter.Call.DestModule, destVerb)) + case *pbconsole.EventsQuery_Filter_Module: + var verb optional.Option[string] + if filter.Module.Verb != nil { + verb = optional.Some(*filter.Module.Verb) + } + query = append(query, timeline.FilterModule(filter.Module.Module, verb)) default: return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("unknown filter %T", filter)) diff --git a/backend/controller/timeline/query.go b/backend/controller/timeline/query.go index 5bb0317aa8..f8f3f43f89 100644 --- a/backend/controller/timeline/query.go +++ b/backend/controller/timeline/query.go @@ -22,9 +22,15 @@ type eventFilterCall struct { destVerb optional.Option[string] } +type eventFilterModule struct { + module string + verb optional.Option[string] +} + type eventFilter struct { level *log.Level calls []*eventFilterCall + module []*eventFilterModule types []EventType deployments []model.DeploymentKey requests []string @@ -58,6 +64,12 @@ func FilterCall(sourceModule optional.Option[string], destModule string, destVer } } +func FilterModule(module string, verb optional.Option[string]) TimelineFilter { + return func(query *eventFilter) { + query.module = append(query.module, &eventFilterModule{module: module, verb: verb}) + } +} + func FilterDeployments(deploymentKeys ...model.DeploymentKey) TimelineFilter { return func(query *eventFilter) { query.deployments = append(query.deployments, deploymentKeys...) @@ -205,6 +217,23 @@ func (s *Service) QueryTimeline(ctx context.Context, limit int, filters ...Timel q += ")\n" } + if len(filter.module) > 0 { + q += " AND (" + for i, module := range filter.module { + if i > 0 { + q += " OR " + } + if verb, ok := module.verb.Get(); ok { + q += fmt.Sprintf("((e.type = 'call' AND e.custom_key_3 = $%d AND e.custom_key_4 = $%d) OR (e.type = 'ingress' AND e.custom_key_1 = $%d AND e.custom_key_2 = $%d))", + param(module.module), param(verb), param(module.module), param(verb)) + } else { + q += fmt.Sprintf("((e.type = 'call' AND e.custom_key_3 = $%d) OR (e.type = 'ingress' AND e.custom_key_1 = $%d))", + param(module.module), param(module.module)) + } + } + q += ")\n" + } + if filter.descending { q += " ORDER BY e.time_stamp DESC, e.id DESC" } else { diff --git a/backend/controller/timeline/timeline_test.go b/backend/controller/timeline/timeline_test.go index e3bdef9b4e..b58a9d346e 100644 --- a/backend/controller/timeline/timeline_test.go +++ b/backend/controller/timeline/timeline_test.go @@ -107,7 +107,7 @@ func TestTimeline(t *testing.T) { ingressEvent := &IngressEvent{ DeploymentKey: deploymentKey, RequestKey: optional.Some(requestKey), - Verb: schema.Ref{}, + Verb: schema.Ref{Module: "echo", Name: "echo"}, Method: "GET", Path: "/echo", StatusCode: 200, @@ -169,6 +169,18 @@ func TestTimeline(t *testing.T) { assertEventsEqual(t, []Event{callEvent}, events) }) + t.Run("ByModule", func(t *testing.T) { + events, err := timeline.QueryTimeline(ctx, 1000, FilterTypes(EventTypeIngress), FilterModule("echo", optional.None[string]())) + assert.NoError(t, err) + assertEventsEqual(t, []Event{ingressEvent}, events) + }) + + t.Run("ByModuleWithVerb", func(t *testing.T) { + events, err := timeline.QueryTimeline(ctx, 1000, FilterTypes(EventTypeIngress), FilterModule("echo", optional.Some("echo"))) + assert.NoError(t, err) + assertEventsEqual(t, []Event{ingressEvent}, events) + }) + t.Run("ByLogLevel", func(t *testing.T) { events, err := timeline.QueryTimeline(ctx, 1000, FilterTypes(EventTypeLog), FilterLogLevel(log.Trace)) assert.NoError(t, err) diff --git a/backend/protos/xyz/block/ftl/v1/console/console.pb.go b/backend/protos/xyz/block/ftl/v1/console/console.pb.go index d2fab86198..7964c5af8f 100644 --- a/backend/protos/xyz/block/ftl/v1/console/console.pb.go +++ b/backend/protos/xyz/block/ftl/v1/console/console.pb.go @@ -2259,6 +2259,61 @@ func (x *EventsQuery_CallFilter) GetSourceModule() string { return "" } +type EventsQuery_ModuleFilter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Module string `protobuf:"bytes,1,opt,name=module,proto3" json:"module,omitempty"` + Verb *string `protobuf:"bytes,2,opt,name=verb,proto3,oneof" json:"verb,omitempty"` +} + +func (x *EventsQuery_ModuleFilter) Reset() { + *x = EventsQuery_ModuleFilter{} + if protoimpl.UnsafeEnabled { + mi := &file_xyz_block_ftl_v1_console_console_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EventsQuery_ModuleFilter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EventsQuery_ModuleFilter) ProtoMessage() {} + +func (x *EventsQuery_ModuleFilter) ProtoReflect() protoreflect.Message { + mi := &file_xyz_block_ftl_v1_console_console_proto_msgTypes[34] + 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 EventsQuery_ModuleFilter.ProtoReflect.Descriptor instead. +func (*EventsQuery_ModuleFilter) Descriptor() ([]byte, []int) { + return file_xyz_block_ftl_v1_console_console_proto_rawDescGZIP(), []int{20, 8} +} + +func (x *EventsQuery_ModuleFilter) GetModule() string { + if x != nil { + return x.Module + } + return "" +} + +func (x *EventsQuery_ModuleFilter) GetVerb() string { + if x != nil && x.Verb != nil { + return *x.Verb + } + return "" +} + type EventsQuery_Filter struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2276,13 +2331,14 @@ type EventsQuery_Filter struct { // *EventsQuery_Filter_Time // *EventsQuery_Filter_Id // *EventsQuery_Filter_Call + // *EventsQuery_Filter_Module Filter isEventsQuery_Filter_Filter `protobuf_oneof:"filter"` } func (x *EventsQuery_Filter) Reset() { *x = EventsQuery_Filter{} if protoimpl.UnsafeEnabled { - mi := &file_xyz_block_ftl_v1_console_console_proto_msgTypes[34] + mi := &file_xyz_block_ftl_v1_console_console_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2295,7 +2351,7 @@ func (x *EventsQuery_Filter) String() string { func (*EventsQuery_Filter) ProtoMessage() {} func (x *EventsQuery_Filter) ProtoReflect() protoreflect.Message { - mi := &file_xyz_block_ftl_v1_console_console_proto_msgTypes[34] + mi := &file_xyz_block_ftl_v1_console_console_proto_msgTypes[35] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2308,7 +2364,7 @@ func (x *EventsQuery_Filter) ProtoReflect() protoreflect.Message { // Deprecated: Use EventsQuery_Filter.ProtoReflect.Descriptor instead. func (*EventsQuery_Filter) Descriptor() ([]byte, []int) { - return file_xyz_block_ftl_v1_console_console_proto_rawDescGZIP(), []int{20, 8} + return file_xyz_block_ftl_v1_console_console_proto_rawDescGZIP(), []int{20, 9} } func (m *EventsQuery_Filter) GetFilter() isEventsQuery_Filter_Filter { @@ -2374,6 +2430,13 @@ func (x *EventsQuery_Filter) GetCall() *EventsQuery_CallFilter { return nil } +func (x *EventsQuery_Filter) GetModule() *EventsQuery_ModuleFilter { + if x, ok := x.GetFilter().(*EventsQuery_Filter_Module); ok { + return x.Module + } + return nil +} + type isEventsQuery_Filter_Filter interface { isEventsQuery_Filter_Filter() } @@ -2410,6 +2473,10 @@ type EventsQuery_Filter_Call struct { Call *EventsQuery_CallFilter `protobuf:"bytes,8,opt,name=call,proto3,oneof"` } +type EventsQuery_Filter_Module struct { + Module *EventsQuery_ModuleFilter `protobuf:"bytes,9,opt,name=module,proto3,oneof"` +} + func (*EventsQuery_Filter_Limit) isEventsQuery_Filter_Filter() {} func (*EventsQuery_Filter_LogLevel) isEventsQuery_Filter_Filter() {} @@ -2426,6 +2493,8 @@ func (*EventsQuery_Filter_Id) isEventsQuery_Filter_Filter() {} func (*EventsQuery_Filter_Call) isEventsQuery_Filter_Filter() {} +func (*EventsQuery_Filter_Module) isEventsQuery_Filter_Filter() {} + var File_xyz_block_ftl_v1_console_console_proto protoreflect.FileDescriptor var file_xyz_block_ftl_v1_console_console_proto_rawDesc = []byte{ @@ -2642,7 +2711,7 @@ var file_xyz_block_ftl_v1_console_console_proto_rawDesc = []byte{ 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, - 0x67, 0x79, 0x52, 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x22, 0xcc, 0x0c, 0x0a, + 0x67, 0x79, 0x52, 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x22, 0xe4, 0x0d, 0x0a, 0x0b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x46, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, @@ -2701,153 +2770,163 @@ var file_xyz_block_ftl_v1_console_console_proto_rawDesc = []byte{ 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x64, 0x65, 0x73, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x62, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x1a, - 0x8d, 0x05, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x49, 0x0a, 0x05, 0x6c, 0x69, - 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x78, 0x79, 0x7a, 0x2e, + 0x48, 0x0a, 0x0c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, + 0x16, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x17, 0x0a, 0x04, 0x76, 0x65, 0x72, 0x62, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x76, 0x65, 0x72, 0x62, 0x88, 0x01, 0x01, + 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x76, 0x65, 0x72, 0x62, 0x1a, 0xdb, 0x05, 0x0a, 0x06, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x12, 0x49, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, + 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x73, 0x51, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x6d, 0x69, 0x74, + 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, + 0x53, 0x0a, 0x09, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, + 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x73, 0x51, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, + 0x65, 0x6c, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x08, 0x6c, 0x6f, 0x67, 0x4c, + 0x65, 0x76, 0x65, 0x6c, 0x12, 0x5a, 0x0a, 0x0b, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x2e, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x05, - 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x53, 0x0a, 0x09, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x65, 0x76, - 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, - 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x6f, 0x6c, 0x65, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x51, 0x75, 0x65, 0x72, 0x79, 0x2e, - 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x48, 0x00, - 0x52, 0x08, 0x6c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x5a, 0x0a, 0x0b, 0x64, 0x65, - 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x36, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, - 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x73, 0x51, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, - 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0b, 0x64, 0x65, 0x70, 0x6c, 0x6f, - 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x51, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, + 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x48, 0x00, 0x52, 0x0b, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x12, 0x51, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, + 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x73, 0x51, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x73, 0x12, 0x58, 0x0a, 0x0b, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x51, 0x75, 0x65, 0x72, 0x79, 0x2e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, - 0x08, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x58, 0x0a, 0x0b, 0x65, 0x76, 0x65, - 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, - 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, - 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, - 0x51, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x46, - 0x69, 0x6c, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0a, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, - 0x70, 0x65, 0x73, 0x12, 0x46, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x30, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, - 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x73, 0x51, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x46, 0x69, 0x6c, - 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x40, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, - 0x6c, 0x65, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x51, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x49, - 0x44, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x02, 0x69, 0x64, 0x12, 0x46, 0x0a, - 0x04, 0x63, 0x61, 0x6c, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x78, 0x79, - 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, - 0x04, 0x63, 0x61, 0x6c, 0x6c, 0x42, 0x08, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, - 0x1a, 0x0a, 0x05, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x53, 0x43, 0x10, - 0x00, 0x12, 0x08, 0x0a, 0x04, 0x44, 0x45, 0x53, 0x43, 0x10, 0x01, 0x22, 0xaf, 0x01, 0x0a, 0x13, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x47, 0x0a, 0x0f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, - 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x0e, 0x75, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x3b, 0x0a, 0x05, - 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x78, 0x79, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x48, + 0x00, 0x52, 0x0a, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x46, 0x0a, + 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x42, 0x12, 0x0a, 0x10, 0x5f, 0x75, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x22, 0x4f, 0x0a, - 0x14, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, - 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xd8, - 0x03, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x74, 0x69, 0x6d, 0x65, - 0x5f, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x74, - 0x61, 0x6d, 0x70, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x02, 0x69, 0x64, 0x12, 0x36, 0x0a, 0x03, 0x6c, 0x6f, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x22, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, - 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x4c, 0x6f, 0x67, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x03, 0x6c, 0x6f, 0x67, 0x12, 0x39, 0x0a, 0x04, 0x63, - 0x61, 0x6c, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x78, 0x79, 0x7a, 0x2e, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, - 0x52, 0x04, 0x63, 0x61, 0x6c, 0x6c, 0x12, 0x61, 0x0a, 0x12, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, - 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, - 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x44, 0x65, - 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x11, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, - 0x6e, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x12, 0x61, 0x0a, 0x12, 0x64, 0x65, 0x70, - 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, + 0x72, 0x79, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, + 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x40, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x2e, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, + 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x73, 0x51, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x49, 0x44, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x48, 0x00, 0x52, 0x02, 0x69, 0x64, 0x12, 0x46, 0x0a, 0x04, 0x63, 0x61, 0x6c, 0x6c, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, - 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x11, 0x64, 0x65, 0x70, 0x6c, 0x6f, - 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x12, 0x42, 0x0a, 0x07, - 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, + 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x51, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x43, 0x61, 0x6c, + 0x6c, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x04, 0x63, 0x61, 0x6c, 0x6c, 0x12, + 0x4c, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x32, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, + 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x73, 0x51, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x46, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x42, 0x08, 0x0a, + 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x1a, 0x0a, 0x05, 0x4f, 0x72, 0x64, 0x65, 0x72, + 0x12, 0x07, 0x0a, 0x03, 0x41, 0x53, 0x43, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x44, 0x45, 0x53, + 0x43, 0x10, 0x01, 0x22, 0xaf, 0x01, 0x0a, 0x13, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x47, 0x0a, 0x0f, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, + 0x00, 0x52, 0x0e, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, + 0x6c, 0x88, 0x01, 0x01, 0x12, 0x3b, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, + 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x73, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, + 0x79, 0x42, 0x12, 0x0a, 0x10, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x76, 0x61, 0x6c, 0x22, 0x4f, 0x0a, 0x14, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, + 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x07, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, - 0x42, 0x07, 0x0a, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x22, 0x74, 0x0a, 0x11, 0x47, 0x65, 0x74, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, - 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, - 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, - 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, - 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1b, 0x0a, 0x06, 0x63, 0x75, 0x72, 0x73, 0x6f, - 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x06, 0x63, 0x75, 0x72, 0x73, 0x6f, - 0x72, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x2a, - 0xaa, 0x01, 0x0a, 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, - 0x12, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, - 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x4f, 0x47, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x45, 0x56, 0x45, - 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x10, 0x02, 0x12, 0x21, - 0x0a, 0x1d, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x45, 0x50, - 0x4c, 0x4f, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, - 0x03, 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, - 0x44, 0x45, 0x50, 0x4c, 0x4f, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, - 0x45, 0x44, 0x10, 0x04, 0x12, 0x16, 0x0a, 0x12, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x05, 0x2a, 0x88, 0x01, 0x0a, - 0x08, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x15, 0x0a, 0x11, 0x4c, 0x4f, 0x47, - 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, - 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x54, 0x52, - 0x41, 0x43, 0x45, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, - 0x45, 0x4c, 0x5f, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x05, 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x4f, - 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x09, 0x12, 0x12, - 0x0a, 0x0e, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x57, 0x41, 0x52, 0x4e, - 0x10, 0x0d, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x11, 0x32, 0x97, 0x03, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x73, - 0x6f, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4a, 0x0a, 0x04, 0x50, 0x69, - 0x6e, 0x67, 0x12, 0x1d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, - 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1e, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, - 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x67, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, - 0x75, 0x6c, 0x65, 0x73, 0x12, 0x2b, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, - 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2c, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, - 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x47, 0x65, 0x74, - 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x6f, 0x0a, 0x0c, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, - 0x2d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, - 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, - 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, - 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, - 0x12, 0x5f, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x25, 0x2e, + 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xd8, 0x03, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x12, 0x39, 0x0a, 0x0a, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x36, 0x0a, 0x03, 0x6c, + 0x6f, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, + 0x6f, 0x6c, 0x65, 0x2e, 0x4c, 0x6f, 0x67, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x03, + 0x6c, 0x6f, 0x67, 0x12, 0x39, 0x0a, 0x04, 0x63, 0x61, 0x6c, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x23, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, + 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x43, 0x61, 0x6c, + 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x04, 0x63, 0x61, 0x6c, 0x6c, 0x12, 0x61, + 0x0a, 0x12, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x78, 0x79, 0x7a, + 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, + 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x11, + 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x12, 0x61, 0x0a, 0x12, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x1a, 0x2b, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, - 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x42, 0x50, 0x50, 0x01, 0x5a, 0x4c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x54, 0x42, 0x44, 0x35, 0x34, 0x35, 0x36, 0x36, 0x39, 0x37, 0x35, 0x2f, 0x66, 0x74, - 0x6c, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, - 0x2f, 0x78, 0x79, 0x7a, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2f, 0x66, 0x74, 0x6c, 0x2f, 0x76, - 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x3b, 0x70, 0x62, 0x63, 0x6f, 0x6e, 0x73, - 0x6f, 0x6c, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, + 0x65, 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, + 0x00, 0x52, 0x11, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x64, 0x12, 0x42, 0x0a, 0x07, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, + 0x2e, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, + 0x07, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x6e, 0x74, 0x72, + 0x79, 0x22, 0x74, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, + 0x65, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, + 0x1b, 0x0a, 0x06, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x48, + 0x00, 0x52, 0x06, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, + 0x5f, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x2a, 0xaa, 0x01, 0x0a, 0x09, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x54, + 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x12, 0x0a, + 0x0e, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x4f, 0x47, 0x10, + 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x43, 0x41, 0x4c, 0x4c, 0x10, 0x02, 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x45, 0x50, 0x4c, 0x4f, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, + 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, 0x03, 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x56, 0x45, + 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x45, 0x50, 0x4c, 0x4f, 0x59, 0x4d, 0x45, + 0x4e, 0x54, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x44, 0x10, 0x04, 0x12, 0x16, 0x0a, 0x12, + 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x47, 0x52, 0x45, + 0x53, 0x53, 0x10, 0x05, 0x2a, 0x88, 0x01, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, + 0x6c, 0x12, 0x15, 0x0a, 0x11, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x55, + 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, 0x47, 0x5f, + 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x54, 0x52, 0x41, 0x43, 0x45, 0x10, 0x01, 0x12, 0x13, 0x0a, + 0x0f, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x44, 0x45, 0x42, 0x55, 0x47, + 0x10, 0x05, 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, + 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x09, 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, + 0x56, 0x45, 0x4c, 0x5f, 0x57, 0x41, 0x52, 0x4e, 0x10, 0x0d, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, + 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x11, 0x32, + 0x97, 0x03, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x4a, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x1d, 0x2e, 0x78, 0x79, 0x7a, + 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, + 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x78, 0x79, 0x7a, 0x2e, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, + 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x67, + 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x2b, 0x2e, 0x78, + 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, + 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, + 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x78, 0x79, 0x7a, 0x2e, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, + 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6f, 0x0a, 0x0c, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x2d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, + 0x6c, 0x65, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, + 0x65, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x5f, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x25, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, + 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x51, 0x75, 0x65, 0x72, 0x79, 0x1a, 0x2b, 0x2e, 0x78, + 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, + 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x50, 0x50, 0x01, 0x5a, 0x4c, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x42, 0x44, 0x35, 0x34, 0x35, + 0x36, 0x36, 0x39, 0x37, 0x35, 0x2f, 0x66, 0x74, 0x6c, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, + 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x78, 0x79, 0x7a, 0x2f, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x2f, 0x66, 0x74, 0x6c, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, + 0x65, 0x3b, 0x70, 0x62, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -2863,7 +2942,7 @@ func file_xyz_block_ftl_v1_console_console_proto_rawDescGZIP() []byte { } var file_xyz_block_ftl_v1_console_console_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_xyz_block_ftl_v1_console_console_proto_msgTypes = make([]protoimpl.MessageInfo, 35) +var file_xyz_block_ftl_v1_console_console_proto_msgTypes = make([]protoimpl.MessageInfo, 36) var file_xyz_block_ftl_v1_console_console_proto_goTypes = []any{ (EventType)(0), // 0: xyz.block.ftl.v1.console.EventType (LogLevel)(0), // 1: xyz.block.ftl.v1.console.LogLevel @@ -2902,43 +2981,44 @@ var file_xyz_block_ftl_v1_console_console_proto_goTypes = []any{ (*EventsQuery_TimeFilter)(nil), // 34: xyz.block.ftl.v1.console.EventsQuery.TimeFilter (*EventsQuery_IDFilter)(nil), // 35: xyz.block.ftl.v1.console.EventsQuery.IDFilter (*EventsQuery_CallFilter)(nil), // 36: xyz.block.ftl.v1.console.EventsQuery.CallFilter - (*EventsQuery_Filter)(nil), // 37: xyz.block.ftl.v1.console.EventsQuery.Filter - (*timestamppb.Timestamp)(nil), // 38: google.protobuf.Timestamp - (*schema.Ref)(nil), // 39: xyz.block.ftl.v1.schema.Ref - (*durationpb.Duration)(nil), // 40: google.protobuf.Duration - (*schema.Config)(nil), // 41: xyz.block.ftl.v1.schema.Config - (*schema.Data)(nil), // 42: xyz.block.ftl.v1.schema.Data - (*schema.Database)(nil), // 43: xyz.block.ftl.v1.schema.Database - (*schema.Enum)(nil), // 44: xyz.block.ftl.v1.schema.Enum - (*schema.FSM)(nil), // 45: xyz.block.ftl.v1.schema.FSM - (*schema.Topic)(nil), // 46: xyz.block.ftl.v1.schema.Topic - (*schema.TypeAlias)(nil), // 47: xyz.block.ftl.v1.schema.TypeAlias - (*schema.Secret)(nil), // 48: xyz.block.ftl.v1.schema.Secret - (*schema.Subscription)(nil), // 49: xyz.block.ftl.v1.schema.Subscription - (*schema.Verb)(nil), // 50: xyz.block.ftl.v1.schema.Verb - (*v1.PingRequest)(nil), // 51: xyz.block.ftl.v1.PingRequest - (*v1.PingResponse)(nil), // 52: xyz.block.ftl.v1.PingResponse + (*EventsQuery_ModuleFilter)(nil), // 37: xyz.block.ftl.v1.console.EventsQuery.ModuleFilter + (*EventsQuery_Filter)(nil), // 38: xyz.block.ftl.v1.console.EventsQuery.Filter + (*timestamppb.Timestamp)(nil), // 39: google.protobuf.Timestamp + (*schema.Ref)(nil), // 40: xyz.block.ftl.v1.schema.Ref + (*durationpb.Duration)(nil), // 41: google.protobuf.Duration + (*schema.Config)(nil), // 42: xyz.block.ftl.v1.schema.Config + (*schema.Data)(nil), // 43: xyz.block.ftl.v1.schema.Data + (*schema.Database)(nil), // 44: xyz.block.ftl.v1.schema.Database + (*schema.Enum)(nil), // 45: xyz.block.ftl.v1.schema.Enum + (*schema.FSM)(nil), // 46: xyz.block.ftl.v1.schema.FSM + (*schema.Topic)(nil), // 47: xyz.block.ftl.v1.schema.Topic + (*schema.TypeAlias)(nil), // 48: xyz.block.ftl.v1.schema.TypeAlias + (*schema.Secret)(nil), // 49: xyz.block.ftl.v1.schema.Secret + (*schema.Subscription)(nil), // 50: xyz.block.ftl.v1.schema.Subscription + (*schema.Verb)(nil), // 51: xyz.block.ftl.v1.schema.Verb + (*v1.PingRequest)(nil), // 52: xyz.block.ftl.v1.PingRequest + (*v1.PingResponse)(nil), // 53: xyz.block.ftl.v1.PingResponse } var file_xyz_block_ftl_v1_console_console_proto_depIdxs = []int32{ - 38, // 0: xyz.block.ftl.v1.console.LogEvent.time_stamp:type_name -> google.protobuf.Timestamp + 39, // 0: xyz.block.ftl.v1.console.LogEvent.time_stamp:type_name -> google.protobuf.Timestamp 28, // 1: xyz.block.ftl.v1.console.LogEvent.attributes:type_name -> xyz.block.ftl.v1.console.LogEvent.AttributesEntry - 38, // 2: xyz.block.ftl.v1.console.CallEvent.time_stamp:type_name -> google.protobuf.Timestamp - 39, // 3: xyz.block.ftl.v1.console.CallEvent.source_verb_ref:type_name -> xyz.block.ftl.v1.schema.Ref - 39, // 4: xyz.block.ftl.v1.console.CallEvent.destination_verb_ref:type_name -> xyz.block.ftl.v1.schema.Ref - 40, // 5: xyz.block.ftl.v1.console.CallEvent.duration:type_name -> google.protobuf.Duration - 39, // 6: xyz.block.ftl.v1.console.IngressEvent.verb_ref:type_name -> xyz.block.ftl.v1.schema.Ref - 38, // 7: xyz.block.ftl.v1.console.IngressEvent.time_stamp:type_name -> google.protobuf.Timestamp - 40, // 8: xyz.block.ftl.v1.console.IngressEvent.duration:type_name -> google.protobuf.Duration - 41, // 9: xyz.block.ftl.v1.console.Config.config:type_name -> xyz.block.ftl.v1.schema.Config - 42, // 10: xyz.block.ftl.v1.console.Data.data:type_name -> xyz.block.ftl.v1.schema.Data - 43, // 11: xyz.block.ftl.v1.console.Database.database:type_name -> xyz.block.ftl.v1.schema.Database - 44, // 12: xyz.block.ftl.v1.console.Enum.enum:type_name -> xyz.block.ftl.v1.schema.Enum - 45, // 13: xyz.block.ftl.v1.console.FSM.fsm:type_name -> xyz.block.ftl.v1.schema.FSM - 46, // 14: xyz.block.ftl.v1.console.Topic.topic:type_name -> xyz.block.ftl.v1.schema.Topic - 47, // 15: xyz.block.ftl.v1.console.TypeAlias.typealias:type_name -> xyz.block.ftl.v1.schema.TypeAlias - 48, // 16: xyz.block.ftl.v1.console.Secret.secret:type_name -> xyz.block.ftl.v1.schema.Secret - 49, // 17: xyz.block.ftl.v1.console.Subscription.subscription:type_name -> xyz.block.ftl.v1.schema.Subscription - 50, // 18: xyz.block.ftl.v1.console.Verb.verb:type_name -> xyz.block.ftl.v1.schema.Verb + 39, // 2: xyz.block.ftl.v1.console.CallEvent.time_stamp:type_name -> google.protobuf.Timestamp + 40, // 3: xyz.block.ftl.v1.console.CallEvent.source_verb_ref:type_name -> xyz.block.ftl.v1.schema.Ref + 40, // 4: xyz.block.ftl.v1.console.CallEvent.destination_verb_ref:type_name -> xyz.block.ftl.v1.schema.Ref + 41, // 5: xyz.block.ftl.v1.console.CallEvent.duration:type_name -> google.protobuf.Duration + 40, // 6: xyz.block.ftl.v1.console.IngressEvent.verb_ref:type_name -> xyz.block.ftl.v1.schema.Ref + 39, // 7: xyz.block.ftl.v1.console.IngressEvent.time_stamp:type_name -> google.protobuf.Timestamp + 41, // 8: xyz.block.ftl.v1.console.IngressEvent.duration:type_name -> google.protobuf.Duration + 42, // 9: xyz.block.ftl.v1.console.Config.config:type_name -> xyz.block.ftl.v1.schema.Config + 43, // 10: xyz.block.ftl.v1.console.Data.data:type_name -> xyz.block.ftl.v1.schema.Data + 44, // 11: xyz.block.ftl.v1.console.Database.database:type_name -> xyz.block.ftl.v1.schema.Database + 45, // 12: xyz.block.ftl.v1.console.Enum.enum:type_name -> xyz.block.ftl.v1.schema.Enum + 46, // 13: xyz.block.ftl.v1.console.FSM.fsm:type_name -> xyz.block.ftl.v1.schema.FSM + 47, // 14: xyz.block.ftl.v1.console.Topic.topic:type_name -> xyz.block.ftl.v1.schema.Topic + 48, // 15: xyz.block.ftl.v1.console.TypeAlias.typealias:type_name -> xyz.block.ftl.v1.schema.TypeAlias + 49, // 16: xyz.block.ftl.v1.console.Secret.secret:type_name -> xyz.block.ftl.v1.schema.Secret + 50, // 17: xyz.block.ftl.v1.console.Subscription.subscription:type_name -> xyz.block.ftl.v1.schema.Subscription + 51, // 18: xyz.block.ftl.v1.console.Verb.verb:type_name -> xyz.block.ftl.v1.schema.Verb 17, // 19: xyz.block.ftl.v1.console.Module.verbs:type_name -> xyz.block.ftl.v1.console.Verb 9, // 20: xyz.block.ftl.v1.console.Module.data:type_name -> xyz.block.ftl.v1.console.Data 15, // 21: xyz.block.ftl.v1.console.Module.secrets:type_name -> xyz.block.ftl.v1.console.Secret @@ -2946,12 +3026,12 @@ var file_xyz_block_ftl_v1_console_console_proto_depIdxs = []int32{ 19, // 23: xyz.block.ftl.v1.console.Topology.levels:type_name -> xyz.block.ftl.v1.console.TopologyGroup 18, // 24: xyz.block.ftl.v1.console.GetModulesResponse.modules:type_name -> xyz.block.ftl.v1.console.Module 20, // 25: xyz.block.ftl.v1.console.GetModulesResponse.topology:type_name -> xyz.block.ftl.v1.console.Topology - 37, // 26: xyz.block.ftl.v1.console.EventsQuery.filters:type_name -> xyz.block.ftl.v1.console.EventsQuery.Filter + 38, // 26: xyz.block.ftl.v1.console.EventsQuery.filters:type_name -> xyz.block.ftl.v1.console.EventsQuery.Filter 2, // 27: xyz.block.ftl.v1.console.EventsQuery.order:type_name -> xyz.block.ftl.v1.console.EventsQuery.Order - 40, // 28: xyz.block.ftl.v1.console.StreamEventsRequest.update_interval:type_name -> google.protobuf.Duration + 41, // 28: xyz.block.ftl.v1.console.StreamEventsRequest.update_interval:type_name -> google.protobuf.Duration 23, // 29: xyz.block.ftl.v1.console.StreamEventsRequest.query:type_name -> xyz.block.ftl.v1.console.EventsQuery 26, // 30: xyz.block.ftl.v1.console.StreamEventsResponse.events:type_name -> xyz.block.ftl.v1.console.Event - 38, // 31: xyz.block.ftl.v1.console.Event.time_stamp:type_name -> google.protobuf.Timestamp + 39, // 31: xyz.block.ftl.v1.console.Event.time_stamp:type_name -> google.protobuf.Timestamp 3, // 32: xyz.block.ftl.v1.console.Event.log:type_name -> xyz.block.ftl.v1.console.LogEvent 4, // 33: xyz.block.ftl.v1.console.Event.call:type_name -> xyz.block.ftl.v1.console.CallEvent 5, // 34: xyz.block.ftl.v1.console.Event.deployment_created:type_name -> xyz.block.ftl.v1.console.DeploymentCreatedEvent @@ -2960,8 +3040,8 @@ var file_xyz_block_ftl_v1_console_console_proto_depIdxs = []int32{ 26, // 37: xyz.block.ftl.v1.console.GetEventsResponse.events:type_name -> xyz.block.ftl.v1.console.Event 1, // 38: xyz.block.ftl.v1.console.EventsQuery.LogLevelFilter.log_level:type_name -> xyz.block.ftl.v1.console.LogLevel 0, // 39: xyz.block.ftl.v1.console.EventsQuery.EventTypeFilter.event_types:type_name -> xyz.block.ftl.v1.console.EventType - 38, // 40: xyz.block.ftl.v1.console.EventsQuery.TimeFilter.older_than:type_name -> google.protobuf.Timestamp - 38, // 41: xyz.block.ftl.v1.console.EventsQuery.TimeFilter.newer_than:type_name -> google.protobuf.Timestamp + 39, // 40: xyz.block.ftl.v1.console.EventsQuery.TimeFilter.older_than:type_name -> google.protobuf.Timestamp + 39, // 41: xyz.block.ftl.v1.console.EventsQuery.TimeFilter.newer_than:type_name -> google.protobuf.Timestamp 29, // 42: xyz.block.ftl.v1.console.EventsQuery.Filter.limit:type_name -> xyz.block.ftl.v1.console.EventsQuery.LimitFilter 30, // 43: xyz.block.ftl.v1.console.EventsQuery.Filter.log_level:type_name -> xyz.block.ftl.v1.console.EventsQuery.LogLevelFilter 31, // 44: xyz.block.ftl.v1.console.EventsQuery.Filter.deployments:type_name -> xyz.block.ftl.v1.console.EventsQuery.DeploymentFilter @@ -2970,19 +3050,20 @@ var file_xyz_block_ftl_v1_console_console_proto_depIdxs = []int32{ 34, // 47: xyz.block.ftl.v1.console.EventsQuery.Filter.time:type_name -> xyz.block.ftl.v1.console.EventsQuery.TimeFilter 35, // 48: xyz.block.ftl.v1.console.EventsQuery.Filter.id:type_name -> xyz.block.ftl.v1.console.EventsQuery.IDFilter 36, // 49: xyz.block.ftl.v1.console.EventsQuery.Filter.call:type_name -> xyz.block.ftl.v1.console.EventsQuery.CallFilter - 51, // 50: xyz.block.ftl.v1.console.ConsoleService.Ping:input_type -> xyz.block.ftl.v1.PingRequest - 21, // 51: xyz.block.ftl.v1.console.ConsoleService.GetModules:input_type -> xyz.block.ftl.v1.console.GetModulesRequest - 24, // 52: xyz.block.ftl.v1.console.ConsoleService.StreamEvents:input_type -> xyz.block.ftl.v1.console.StreamEventsRequest - 23, // 53: xyz.block.ftl.v1.console.ConsoleService.GetEvents:input_type -> xyz.block.ftl.v1.console.EventsQuery - 52, // 54: xyz.block.ftl.v1.console.ConsoleService.Ping:output_type -> xyz.block.ftl.v1.PingResponse - 22, // 55: xyz.block.ftl.v1.console.ConsoleService.GetModules:output_type -> xyz.block.ftl.v1.console.GetModulesResponse - 25, // 56: xyz.block.ftl.v1.console.ConsoleService.StreamEvents:output_type -> xyz.block.ftl.v1.console.StreamEventsResponse - 27, // 57: xyz.block.ftl.v1.console.ConsoleService.GetEvents:output_type -> xyz.block.ftl.v1.console.GetEventsResponse - 54, // [54:58] is the sub-list for method output_type - 50, // [50:54] is the sub-list for method input_type - 50, // [50:50] is the sub-list for extension type_name - 50, // [50:50] is the sub-list for extension extendee - 0, // [0:50] is the sub-list for field type_name + 37, // 50: xyz.block.ftl.v1.console.EventsQuery.Filter.module:type_name -> xyz.block.ftl.v1.console.EventsQuery.ModuleFilter + 52, // 51: xyz.block.ftl.v1.console.ConsoleService.Ping:input_type -> xyz.block.ftl.v1.PingRequest + 21, // 52: xyz.block.ftl.v1.console.ConsoleService.GetModules:input_type -> xyz.block.ftl.v1.console.GetModulesRequest + 24, // 53: xyz.block.ftl.v1.console.ConsoleService.StreamEvents:input_type -> xyz.block.ftl.v1.console.StreamEventsRequest + 23, // 54: xyz.block.ftl.v1.console.ConsoleService.GetEvents:input_type -> xyz.block.ftl.v1.console.EventsQuery + 53, // 55: xyz.block.ftl.v1.console.ConsoleService.Ping:output_type -> xyz.block.ftl.v1.PingResponse + 22, // 56: xyz.block.ftl.v1.console.ConsoleService.GetModules:output_type -> xyz.block.ftl.v1.console.GetModulesResponse + 25, // 57: xyz.block.ftl.v1.console.ConsoleService.StreamEvents:output_type -> xyz.block.ftl.v1.console.StreamEventsResponse + 27, // 58: xyz.block.ftl.v1.console.ConsoleService.GetEvents:output_type -> xyz.block.ftl.v1.console.GetEventsResponse + 55, // [55:59] is the sub-list for method output_type + 51, // [51:55] is the sub-list for method input_type + 51, // [51:51] is the sub-list for extension type_name + 51, // [51:51] is the sub-list for extension extendee + 0, // [0:51] is the sub-list for field type_name } func init() { file_xyz_block_ftl_v1_console_console_proto_init() } @@ -3388,6 +3469,18 @@ func file_xyz_block_ftl_v1_console_console_proto_init() { } } file_xyz_block_ftl_v1_console_console_proto_msgTypes[34].Exporter = func(v any, i int) any { + switch v := v.(*EventsQuery_ModuleFilter); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_xyz_block_ftl_v1_console_console_proto_msgTypes[35].Exporter = func(v any, i int) any { switch v := v.(*EventsQuery_Filter); i { case 0: return &v.state @@ -3416,7 +3509,8 @@ func file_xyz_block_ftl_v1_console_console_proto_init() { file_xyz_block_ftl_v1_console_console_proto_msgTypes[31].OneofWrappers = []any{} file_xyz_block_ftl_v1_console_console_proto_msgTypes[32].OneofWrappers = []any{} file_xyz_block_ftl_v1_console_console_proto_msgTypes[33].OneofWrappers = []any{} - file_xyz_block_ftl_v1_console_console_proto_msgTypes[34].OneofWrappers = []any{ + file_xyz_block_ftl_v1_console_console_proto_msgTypes[34].OneofWrappers = []any{} + file_xyz_block_ftl_v1_console_console_proto_msgTypes[35].OneofWrappers = []any{ (*EventsQuery_Filter_Limit)(nil), (*EventsQuery_Filter_LogLevel)(nil), (*EventsQuery_Filter_Deployments)(nil), @@ -3425,6 +3519,7 @@ func file_xyz_block_ftl_v1_console_console_proto_init() { (*EventsQuery_Filter_Time)(nil), (*EventsQuery_Filter_Id)(nil), (*EventsQuery_Filter_Call)(nil), + (*EventsQuery_Filter_Module)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -3432,7 +3527,7 @@ func file_xyz_block_ftl_v1_console_console_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_xyz_block_ftl_v1_console_console_proto_rawDesc, NumEnums: 3, - NumMessages: 35, + NumMessages: 36, NumExtensions: 0, NumServices: 1, }, diff --git a/backend/protos/xyz/block/ftl/v1/console/console.proto b/backend/protos/xyz/block/ftl/v1/console/console.proto index 90eaf3af60..c3148b83d4 100644 --- a/backend/protos/xyz/block/ftl/v1/console/console.proto +++ b/backend/protos/xyz/block/ftl/v1/console/console.proto @@ -194,6 +194,10 @@ message EventsQuery { optional string dest_verb = 2; optional string source_module = 3; } + message ModuleFilter { + string module = 1; + optional string verb = 2; + } enum Order { ASC = 0; @@ -211,6 +215,7 @@ message EventsQuery { TimeFilter time = 6; IDFilter id = 7; CallFilter call = 8; + ModuleFilter module = 9; } } diff --git a/frontend/console/src/api/timeline/timeline-filters.ts b/frontend/console/src/api/timeline/timeline-filters.ts index c75042cdc8..924616ccff 100644 --- a/frontend/console/src/api/timeline/timeline-filters.ts +++ b/frontend/console/src/api/timeline/timeline-filters.ts @@ -7,6 +7,7 @@ import { EventsQuery_Filter, EventsQuery_IDFilter, EventsQuery_LogLevelFilter, + EventsQuery_ModuleFilter, EventsQuery_RequestFilter, EventsQuery_TimeFilter, type LogLevel, @@ -56,7 +57,7 @@ export const modulesFilter = (modules: string[]): EventsQuery_Filter => { return filter } -export const callFilter = (destModule: string, destVerb: string | undefined = undefined, sourceModule: string | undefined = undefined): EventsQuery_Filter => { +export const callFilter = (destModule: string, destVerb?: string, sourceModule?: string): EventsQuery_Filter => { const filter = new EventsQuery_Filter() const callFilter = new EventsQuery_CallFilter() callFilter.destModule = destModule @@ -69,6 +70,18 @@ export const callFilter = (destModule: string, destVerb: string | undefined = un return filter } +export const moduleFilter = (module: string, verb?: string): EventsQuery_Filter => { + const filter = new EventsQuery_Filter() + const moduleFilter = new EventsQuery_ModuleFilter() + moduleFilter.module = module + moduleFilter.verb = verb + filter.filter = { + case: 'module', + value: moduleFilter, + } + return filter +} + export const timeFilter = (olderThan: Timestamp | undefined, newerThan: Timestamp | undefined): EventsQuery_Filter => { const filter = new EventsQuery_Filter() const timeFilter = new EventsQuery_TimeFilter() diff --git a/frontend/console/src/api/timeline/use-module-trace-events.ts b/frontend/console/src/api/timeline/use-module-trace-events.ts new file mode 100644 index 0000000000..1d41c71c37 --- /dev/null +++ b/frontend/console/src/api/timeline/use-module-trace-events.ts @@ -0,0 +1,15 @@ +import { EventType, type EventsQuery_Filter } from '../../protos/xyz/block/ftl/v1/console/console_pb.ts' +import { eventTypesFilter, moduleFilter } from './timeline-filters.ts' +import { useTimeline } from './use-timeline.ts' + +export const useModuleTraceEvents = (module: string, verb?: string, filters: EventsQuery_Filter[] = []) => { + const eventTypes = [EventType.CALL, EventType.INGRESS] + const allFilters = [...filters, moduleFilter(module, verb), eventTypesFilter(eventTypes)] + const timelineQuery = useTimeline(true, allFilters, 500) + + const data = timelineQuery.data?.filter((event) => event.entry.case === 'call' || event.entry.case === 'ingress') ?? [] + return { + ...timelineQuery, + data, + } +} diff --git a/frontend/console/src/api/timeline/use-request-trace-events.ts b/frontend/console/src/api/timeline/use-request-trace-events.ts index 8489e6768a..885c38da7c 100644 --- a/frontend/console/src/api/timeline/use-request-trace-events.ts +++ b/frontend/console/src/api/timeline/use-request-trace-events.ts @@ -7,7 +7,7 @@ export type TraceEvent = CallEvent | IngressEvent export const useRequestTraceEvents = (requestKey?: string, filters: EventsQuery_Filter[] = []) => { const eventTypes = [EventType.CALL, EventType.INGRESS] const allFilters = [...filters, requestKeysFilter([requestKey || '']), eventTypesFilter(eventTypes)] - const timelineQuery = useTimeline(true, allFilters, !!requestKey) + const timelineQuery = useTimeline(true, allFilters, 500, !!requestKey) const data = timelineQuery.data?.filter((event) => event.entry.case === 'call' || event.entry.case === 'ingress') ?? [] return { diff --git a/frontend/console/src/api/timeline/use-timeline-calls.ts b/frontend/console/src/api/timeline/use-timeline-calls.ts index fa1af09531..0d005d44c2 100644 --- a/frontend/console/src/api/timeline/use-timeline-calls.ts +++ b/frontend/console/src/api/timeline/use-timeline-calls.ts @@ -4,7 +4,7 @@ import { useTimeline } from './use-timeline.ts' export const useTimelineCalls = (isStreaming: boolean, filters: EventsQuery_Filter[], enabled = true) => { const allFilters = [...filters, eventTypesFilter([EventType.CALL])] - const timelineQuery = useTimeline(isStreaming, allFilters, enabled) + const timelineQuery = useTimeline(isStreaming, allFilters, 1000, enabled) const data = timelineQuery.data || [] return { diff --git a/frontend/console/src/api/timeline/use-timeline.ts b/frontend/console/src/api/timeline/use-timeline.ts index c640ca94ae..04c5853374 100644 --- a/frontend/console/src/api/timeline/use-timeline.ts +++ b/frontend/console/src/api/timeline/use-timeline.ts @@ -3,12 +3,12 @@ import { useQuery, useQueryClient } from '@tanstack/react-query' import { useClient } from '../../hooks/use-client' import { useVisibility } from '../../hooks/use-visibility' import { ConsoleService } from '../../protos/xyz/block/ftl/v1/console/console_connect' -import { type EventsQuery_Filter, EventsQuery_Order } from '../../protos/xyz/block/ftl/v1/console/console_pb' +import { type Event, type EventsQuery_Filter, EventsQuery_Order } from '../../protos/xyz/block/ftl/v1/console/console_pb' const timelineKey = 'timeline' const maxTimelineEntries = 1000 -export const useTimeline = (isStreaming: boolean, filters: EventsQuery_Filter[], enabled = true) => { +export const useTimeline = (isStreaming: boolean, filters: EventsQuery_Filter[], updateIntervalMs = 1000, enabled = true) => { const client = useClient(ConsoleService) const queryClient = useQueryClient() const isVisible = useVisibility() @@ -36,12 +36,16 @@ export const useTimeline = (isStreaming: boolean, filters: EventsQuery_Filter[], const streamTimeline = async ({ signal }: { signal: AbortSignal }) => { try { console.debug('streaming timeline') - console.debug('filters:', filters) - for await (const response of client.streamEvents({ updateInterval: { seconds: BigInt(1) }, query: { limit, filters, order } }, { signal })) { + console.debug('timeline-filters:', filters) + for await (const response of client.streamEvents( + { updateInterval: { seconds: BigInt(0), nanos: updateIntervalMs * 1000 }, query: { limit, filters, order } }, + { signal }, + )) { + console.debug('timeline-response:', response) if (response.events) { - const prev = queryClient.getQueryData(queryKey) ?? [] - const allEvents = [...response.events, ...prev].slice(0, maxTimelineEntries) - queryClient.setQueryData(queryKey, allEvents) + queryClient.setQueryData(queryKey, (prev = []) => { + return [...response.events, ...prev].slice(0, maxTimelineEntries) + }) } } } catch (error) { diff --git a/frontend/console/src/features/calls/CallList.tsx b/frontend/console/src/features/calls/CallList.tsx deleted file mode 100644 index a45fdd1f74..0000000000 --- a/frontend/console/src/features/calls/CallList.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import { useContext, useState } from 'react' -import type { CallEvent, Event } from '../../protos/xyz/block/ftl/v1/console/console_pb' -import { SidePanelContext } from '../../providers/side-panel-provider' -import { formatDuration, formatTimestampShort } from '../../utils' -import { TimelineCallDetails } from '../timeline/details/TimelineCallDetails' -import { verbRefString } from '../verbs/verb.utils' - -export const CallList = ({ calls }: { calls: Event[] | undefined }) => { - const { openPanel, closePanel } = useContext(SidePanelContext) - const [selectedCallId, setSelectedCallId] = useState() - - const handleCallClicked = (event: Event) => { - if (selectedCallId === event.id) { - setSelectedCallId(undefined) - closePanel() - return - } - setSelectedCallId(event.id) - openPanel() - } - - return ( -
-
- - - - - - - - - - - - -
DateDur.SourceDestinationRequestResponseError
-
- - - {calls?.map((callEvent, index) => { - const call = callEvent.entry.value as CallEvent - return ( - handleCallClicked(callEvent)} - > - - - - - - - - - ) - })} - -
{formatTimestampShort(callEvent.timeStamp)}{formatDuration(call.duration)} - {call.sourceVerbRef && verbRefString(call.sourceVerbRef)} - - {call.destinationVerbRef && verbRefString(call.destinationVerbRef)} - - {call.request} - - {call.response} - - {call.error} -
-
-
-
- ) -} diff --git a/frontend/console/src/features/timeline/Timeline.tsx b/frontend/console/src/features/timeline/Timeline.tsx index c5c7f1aea5..cc5299662d 100644 --- a/frontend/console/src/features/timeline/Timeline.tsx +++ b/frontend/console/src/features/timeline/Timeline.tsx @@ -4,15 +4,7 @@ import { timeFilter, useTimeline } from '../../api/timeline/index.ts' import { Loader } from '../../components/Loader.tsx' import type { Event, EventsQuery_Filter } from '../../protos/xyz/block/ftl/v1/console/console_pb.ts' import { SidePanelContext } from '../../providers/side-panel-provider.tsx' -import { formatTimestampShort } from '../../utils/date.utils.ts' -import { panelColor } from '../../utils/style.utils.ts' -import { deploymentTextColor } from '../deployments/deployment.utils.ts' -import { TimelineCall } from './TimelineCall.tsx' -import { TimelineDeploymentCreated } from './TimelineDeploymentCreated.tsx' -import { TimelineDeploymentUpdated } from './TimelineDeploymentUpdated.tsx' -import { TimelineIcon } from './TimelineIcon.tsx' -import { TimelineIngress } from './TimelineIngress.tsx' -import { TimelineLog } from './TimelineLog.tsx' +import TimelineEventList from './TimelineEventList.tsx' import { TimelineCallDetails } from './details/TimelineCallDetails.tsx' import { TimelineDeploymentCreatedDetails } from './details/TimelineDeploymentCreatedDetails.tsx' import { TimelineDeploymentUpdatedDetails } from './details/TimelineDeploymentUpdatedDetails.tsx' @@ -76,23 +68,6 @@ export const Timeline = ({ timeSettings, filters }: { timeSettings: TimeSettings setSearchParams({ ...Object.fromEntries(searchParams.entries()), id: entry.id.toString() }) } - const deploymentKey = (event: Event) => { - switch (event.entry?.case) { - case 'call': - return event.entry.value.deploymentKey - case 'log': - return event.entry.value.deploymentKey - case 'deploymentCreated': - return event.entry.value.key - case 'deploymentUpdated': - return event.entry.value.key - case 'ingress': - return event.entry.value.deploymentKey - default: - return '' - } - } - if (timeline.isLoading) { return (
@@ -105,53 +80,7 @@ export const Timeline = ({ timeSettings, filters }: { timeSettings: TimeSettings return (
-
- - - - - - - - - - {entries.map((entry) => ( - handleEntryClicked(entry)} - > - - - - - - ))} - -
- DateDeploymentContent
- - {formatTimestampShort(entry.timeStamp)} - {deploymentKey(entry)} - - {(() => { - switch (entry.entry?.case) { - case 'call': - return - case 'log': - return - case 'deploymentCreated': - return - case 'deploymentUpdated': - return - case 'ingress': - return - } - })()} -
-
+
) } diff --git a/frontend/console/src/features/timeline/TimelineEventList.tsx b/frontend/console/src/features/timeline/TimelineEventList.tsx new file mode 100644 index 0000000000..e7f71ab478 --- /dev/null +++ b/frontend/console/src/features/timeline/TimelineEventList.tsx @@ -0,0 +1,88 @@ +import type { Event } from '../../protos/xyz/block/ftl/v1/console/console_pb' +import { formatTimestampShort } from '../../utils' +import { deploymentTextColor } from '../deployments/deployment.utils' +import { TimelineCall } from './TimelineCall' +import { TimelineDeploymentCreated } from './TimelineDeploymentCreated' +import { TimelineDeploymentUpdated } from './TimelineDeploymentUpdated' +import { TimelineIcon } from './TimelineIcon' +import { TimelineIngress } from './TimelineIngress' +import { TimelineLog } from './TimelineLog' + +interface EventTimelineProps { + events: Event[] + selectedEventId?: bigint + handleEntryClicked: (entry: Event) => void +} + +const deploymentKey = (event: Event) => { + switch (event.entry?.case) { + case 'call': + return event.entry.value.deploymentKey + case 'log': + return event.entry.value.deploymentKey + case 'deploymentCreated': + return event.entry.value.key + case 'deploymentUpdated': + return event.entry.value.key + case 'ingress': + return event.entry.value.deploymentKey + default: + return '' + } +} + +export const TimelineEventList = ({ events, selectedEventId, handleEntryClicked }: EventTimelineProps) => { + return ( +
+ + + + + + + + + + {events.map((entry) => ( + handleEntryClicked(entry)} + > + + + + + + ))} + +
+ DateDeploymentContent
+ + {formatTimestampShort(entry.timeStamp)} + {deploymentKey(entry)} + + {(() => { + switch (entry.entry.case) { + case 'call': + return + case 'log': + return + case 'deploymentCreated': + return + case 'deploymentUpdated': + return + case 'ingress': + return + default: + return null + } + })()} +
+
+ ) +} + +export default TimelineEventList diff --git a/frontend/console/src/features/traces/TraceRequestList.tsx b/frontend/console/src/features/traces/TraceRequestList.tsx new file mode 100644 index 0000000000..4b2b92f316 --- /dev/null +++ b/frontend/console/src/features/traces/TraceRequestList.tsx @@ -0,0 +1,35 @@ +import { useContext, useMemo, useState } from 'react' +import { useModuleTraceEvents } from '../../api/timeline/use-module-trace-events' +import type { Event } from '../../protos/xyz/block/ftl/v1/console/console_pb' +import { SidePanelContext } from '../../providers/side-panel-provider' +import TimelineEventList from '../timeline/TimelineEventList' +import { TimelineCallDetails } from '../timeline/details/TimelineCallDetails' +import { groupEventsByRequestKey } from './traces.utils' + +export const TraceRequestList = ({ module, verb }: { module: string; verb?: string }) => { + const { openPanel, closePanel } = useContext(SidePanelContext) + const [selectedEventId, setSelectedEventId] = useState() + + const traceEventsRequest = useModuleTraceEvents(module, verb) + const traceEvents = useMemo(() => { + return groupEventsByRequestKey(traceEventsRequest.data) + }, [traceEventsRequest.data]) + + const handleCallClicked = (event: Event) => { + if (selectedEventId === event.id) { + setSelectedEventId(undefined) + closePanel() + return + } + setSelectedEventId(event.id) + openPanel() + } + + const events = Object.entries(traceEvents).map(([_, events]) => events[0]) + + return ( +
+ +
+ ) +} diff --git a/frontend/console/src/features/traces/traces.utils.ts b/frontend/console/src/features/traces/traces.utils.ts index 6ee200ae85..6051281e5b 100644 --- a/frontend/console/src/features/traces/traces.utils.ts +++ b/frontend/console/src/features/traces/traces.utils.ts @@ -1,5 +1,6 @@ import type { Timestamp } from '@bufbuild/protobuf' import type { Event } from '../../protos/xyz/block/ftl/v1/console/console_pb' +import { compareTimestamps } from '../../utils' export const eventBarLeftOffsetPercentage = (event: Event, requestStartTime: Timestamp | undefined, requestDurationMs: number) => { if (!requestStartTime) { @@ -16,3 +17,28 @@ export const eventBarLeftOffsetPercentage = (event: Event, requestStartTime: Tim return (offsetInMillis / requestDurationMs) * 100 } + +export const groupEventsByRequestKey = (events: Event[]): Record => { + return events.reduce((acc: Record, event: Event) => { + const requestKey = (() => { + switch (event.entry.case) { + case 'call': + case 'ingress': + return event.entry.value.requestKey + default: + return undefined + } + })() + + if (!requestKey) { + return acc + } + + acc[requestKey] = acc[requestKey] ? [...acc[requestKey], event] : [event] + + // Sort events by timestamp, ensuring the first event is the "trigger" event + acc[requestKey].sort((a, b) => compareTimestamps(a.timeStamp, b.timeStamp)) + + return acc + }, {}) +} diff --git a/frontend/console/src/features/verbs/VerbPage.tsx b/frontend/console/src/features/verbs/VerbPage.tsx index c5f16c8686..eddb922eec 100644 --- a/frontend/console/src/features/verbs/VerbPage.tsx +++ b/frontend/console/src/features/verbs/VerbPage.tsx @@ -2,14 +2,13 @@ import { FunctionIcon } from 'hugeicons-react' import { useContext, useEffect, useState } from 'react' import { useNavigate } from 'react-router-dom' import { useModules } from '../../api/modules/use-modules' -import { useStreamVerbCalls } from '../../api/timeline/stream-verb-calls' import { Loader } from '../../components/Loader' import { ResizablePanels } from '../../components/ResizablePanels' import { Page } from '../../layout' import type { Module, Verb } from '../../protos/xyz/block/ftl/v1/console/console_pb' import { NotificationType, NotificationsContext } from '../../providers/notifications-provider' import { SidePanelProvider } from '../../providers/side-panel-provider' -import { CallList } from '../calls/CallList' +import { TraceRequestList } from '../traces/TraceRequestList' import { VerbRequestForm } from './VerbRequestForm' import { verbPanels } from './VerbRightPanel' @@ -39,9 +38,6 @@ export const VerbPage = ({ moduleName, declName }: { moduleName: string; declNam setVerb(verb) }, [modules.data, moduleName, declName]) - const callEvents = useStreamVerbCalls(module?.name, verb?.verb?.name) - const calls = callEvents.data || [] - if (!module || !verb) { return (
@@ -65,7 +61,7 @@ export const VerbPage = ({ moduleName, declName }: { moduleName: string; declNam mainContent={} rightPanelHeader={header} rightPanelPanels={verbPanels(verb)} - bottomPanelContent={} + bottomPanelContent={} /> diff --git a/frontend/console/src/protos/xyz/block/ftl/v1/console/console_pb.ts b/frontend/console/src/protos/xyz/block/ftl/v1/console/console_pb.ts index 6b591e691e..461e198901 100644 --- a/frontend/console/src/protos/xyz/block/ftl/v1/console/console_pb.ts +++ b/frontend/console/src/protos/xyz/block/ftl/v1/console/console_pb.ts @@ -1510,6 +1510,49 @@ export class EventsQuery_CallFilter extends Message { } } +/** + * @generated from message xyz.block.ftl.v1.console.EventsQuery.ModuleFilter + */ +export class EventsQuery_ModuleFilter extends Message { + /** + * @generated from field: string module = 1; + */ + module = ""; + + /** + * @generated from field: optional string verb = 2; + */ + verb?: string; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "xyz.block.ftl.v1.console.EventsQuery.ModuleFilter"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "module", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 2, name: "verb", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): EventsQuery_ModuleFilter { + return new EventsQuery_ModuleFilter().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): EventsQuery_ModuleFilter { + return new EventsQuery_ModuleFilter().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): EventsQuery_ModuleFilter { + return new EventsQuery_ModuleFilter().fromJsonString(jsonString, options); + } + + static equals(a: EventsQuery_ModuleFilter | PlainMessage | undefined, b: EventsQuery_ModuleFilter | PlainMessage | undefined): boolean { + return proto3.util.equals(EventsQuery_ModuleFilter, a, b); + } +} + /** * @generated from message xyz.block.ftl.v1.console.EventsQuery.Filter */ @@ -1567,6 +1610,12 @@ export class EventsQuery_Filter extends Message { */ value: EventsQuery_CallFilter; case: "call"; + } | { + /** + * @generated from field: xyz.block.ftl.v1.console.EventsQuery.ModuleFilter module = 9; + */ + value: EventsQuery_ModuleFilter; + case: "module"; } | { case: undefined; value?: undefined } = { case: undefined }; constructor(data?: PartialMessage) { @@ -1585,6 +1634,7 @@ export class EventsQuery_Filter extends Message { { no: 6, name: "time", kind: "message", T: EventsQuery_TimeFilter, oneof: "filter" }, { no: 7, name: "id", kind: "message", T: EventsQuery_IDFilter, oneof: "filter" }, { no: 8, name: "call", kind: "message", T: EventsQuery_CallFilter, oneof: "filter" }, + { no: 9, name: "module", kind: "message", T: EventsQuery_ModuleFilter, oneof: "filter" }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): EventsQuery_Filter { diff --git a/frontend/console/src/providers/react-query-provider.tsx b/frontend/console/src/providers/react-query-provider.tsx index 1b3c984089..22937012f1 100644 --- a/frontend/console/src/providers/react-query-provider.tsx +++ b/frontend/console/src/providers/react-query-provider.tsx @@ -1,14 +1,8 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query' -import { ReactQueryDevtools } from '@tanstack/react-query-devtools' import type { PropsWithChildren } from 'react' const queryClient = new QueryClient() export const ReactQueryProvider = ({ children }: PropsWithChildren) => { - return ( - - {children} - - - ) + return {children} } diff --git a/frontend/console/src/utils/date.utils.ts b/frontend/console/src/utils/date.utils.ts index d507c52457..21edec4c5b 100644 --- a/frontend/console/src/utils/date.utils.ts +++ b/frontend/console/src/utils/date.utils.ts @@ -34,3 +34,8 @@ export const formatTimestampTime = (timestamp?: Timestamp): string => { return formattedDate } + +export const compareTimestamps = (a?: Timestamp, b?: Timestamp): number => { + const compareTo = (a?: bigint, b?: bigint): number => Number((a || 0n) - (b || 0n)) + return a?.seconds !== b?.seconds ? compareTo(a?.seconds, b?.seconds) : compareTo(BigInt(a?.nanos || 0), BigInt(b?.nanos || 0)) +}