diff --git a/plugin/debug/index.go b/plugin/debug/index.go index 976ffe84..44e873ec 100644 --- a/plugin/debug/index.go +++ b/plugin/debug/index.go @@ -1,6 +1,7 @@ package plugin_debug import ( + "bytes" "context" "fmt" "io" @@ -54,6 +55,9 @@ func (w *WriteToFile) WriteHeader(statusCode int) { } func (p *DebugPlugin) OnInit() error { + // 启用阻塞分析 + runtime.SetBlockProfileRate(1) // 设置采样率为1纳秒 + if p.Profile != "" { go func() { file, err := os.Create(p.Profile) @@ -251,6 +255,98 @@ func (p *DebugPlugin) GetHeap(ctx context.Context, empty *emptypb.Empty) (*pb.He return resp, nil } +func (p *DebugPlugin) GetCpu(ctx context.Context, empty *emptypb.Empty) (*pb.CpuResponse, error) { + // 创建一个临时文件来存储CPU profile数据 + f, err := os.CreateTemp("", "cpu_profile") + if err != nil { + return nil, fmt.Errorf("could not create CPU profile: %v", err) + } + defer os.Remove(f.Name()) + defer f.Close() + + // 开始CPU profiling + if err := runtimePPROF.StartCPUProfile(f); err != nil { + return nil, fmt.Errorf("could not start CPU profile: %v", err) + } + + // 采样指定时间 + time.Sleep(1 * time.Second) + runtimePPROF.StopCPUProfile() + + // 读取profile数据 + profileData, err := os.ReadFile(f.Name()) + if err != nil { + return nil, fmt.Errorf("could not read CPU profile: %v", err) + } + + // 解析profile数据 + parsedProfile, err := profile.Parse(bytes.NewReader(profileData)) + if err != nil { + return nil, fmt.Errorf("could not parse CPU profile: %v", err) + } + + // 获取阻塞分析数据 + blockBuf := &bytes.Buffer{} + if err := runtimePPROF.Lookup("block").WriteTo(blockBuf, 1); err != nil { + return nil, fmt.Errorf("could not write block profile: %v", err) + } + + // 解析阻塞分析数据 + blockProfile, err := profile.Parse(bytes.NewReader(blockBuf.Bytes())) + if err != nil { + return nil, fmt.Errorf("could not parse block profile: %v", err) + } + + // 计算总阻塞时间 + var totalBlockingTime uint64 + for _, sample := range blockProfile.Sample { + totalBlockingTime += uint64(sample.Value[0]) + } + + // 构建响应 + resp := &pb.CpuResponse{ + Data: &pb.CpuData{ + TotalCpuTimeNs: uint64(parsedProfile.DurationNanos), + SamplingIntervalNs: uint64(parsedProfile.Period), + Functions: make([]*pb.FunctionProfile, 0), + Goroutines: make([]*pb.GoroutineProfile, 0), + SystemCalls: make([]*pb.SystemCall, 0), + RuntimeStats: &pb.RuntimeStats{}, + }, + } + + // 收集函数调用信息 + for _, sample := range parsedProfile.Sample { + functionProfile := &pb.FunctionProfile{ + FunctionName: sample.Location[0].Line[0].Function.Name, + CpuTimeNs: uint64(sample.Value[0]), + InvocationCount: uint64(sample.Value[1]), + CallStack: make([]string, 0), + } + + // 收集调用栈信息 + for _, loc := range sample.Location { + for _, line := range loc.Line { + functionProfile.CallStack = append(functionProfile.CallStack, line.Function.Name) + } + } + + resp.Data.Functions = append(resp.Data.Functions, functionProfile) + } + + // 收集运行时统计信息 + var memStats runtime.MemStats + runtime.ReadMemStats(&memStats) + resp.Data.RuntimeStats = &pb.RuntimeStats{ + GcCpuFraction: memStats.GCCPUFraction, + GcCount: uint64(memStats.NumGC), + GcPauseTimeNs: memStats.PauseTotalNs, + BlockingTimeNs: totalBlockingTime, // 添加阻塞时间统计 + } + + return resp, nil +} + // 辅助函数:检查字符串切片是否包含特定字符串 func contains(slice []string, str string) bool { for _, s := range slice { diff --git a/plugin/debug/pb/debug.pb.go b/plugin/debug/pb/debug.pb.go index bfe8e907..f211b2af 100644 --- a/plugin/debug/pb/debug.pb.go +++ b/plugin/debug/pb/debug.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 -// protoc v3.19.1 +// protoc-gen-go v1.36.0 +// protoc v5.29.1 // source: debug.proto package pb @@ -24,25 +24,22 @@ const ( ) type HeapObject struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + Count int64 `protobuf:"varint,2,opt,name=count,proto3" json:"count,omitempty"` + Size int64 `protobuf:"varint,3,opt,name=size,proto3" json:"size,omitempty"` + SizePerc float64 `protobuf:"fixed64,4,opt,name=sizePerc,proto3" json:"sizePerc,omitempty"` + Address string `protobuf:"bytes,5,opt,name=address,proto3" json:"address,omitempty"` + Refs []string `protobuf:"bytes,6,rep,name=refs,proto3" json:"refs,omitempty"` unknownFields protoimpl.UnknownFields - - Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` - Count int64 `protobuf:"varint,2,opt,name=count,proto3" json:"count,omitempty"` - Size int64 `protobuf:"varint,3,opt,name=size,proto3" json:"size,omitempty"` - SizePerc float64 `protobuf:"fixed64,4,opt,name=sizePerc,proto3" json:"sizePerc,omitempty"` - Address string `protobuf:"bytes,5,opt,name=address,proto3" json:"address,omitempty"` - Refs []string `protobuf:"bytes,6,rep,name=refs,proto3" json:"refs,omitempty"` + sizeCache protoimpl.SizeCache } func (x *HeapObject) Reset() { *x = HeapObject{} - if protoimpl.UnsafeEnabled { - mi := &file_debug_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_debug_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *HeapObject) String() string { @@ -53,7 +50,7 @@ func (*HeapObject) ProtoMessage() {} func (x *HeapObject) ProtoReflect() protoreflect.Message { mi := &file_debug_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -111,30 +108,27 @@ func (x *HeapObject) GetRefs() []string { } type HeapStats struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Alloc uint64 `protobuf:"varint,1,opt,name=alloc,proto3" json:"alloc,omitempty"` + TotalAlloc uint64 `protobuf:"varint,2,opt,name=totalAlloc,proto3" json:"totalAlloc,omitempty"` + Sys uint64 `protobuf:"varint,3,opt,name=sys,proto3" json:"sys,omitempty"` + NumGC uint32 `protobuf:"varint,4,opt,name=numGC,proto3" json:"numGC,omitempty"` + HeapAlloc uint64 `protobuf:"varint,5,opt,name=heapAlloc,proto3" json:"heapAlloc,omitempty"` + HeapSys uint64 `protobuf:"varint,6,opt,name=heapSys,proto3" json:"heapSys,omitempty"` + HeapIdle uint64 `protobuf:"varint,7,opt,name=heapIdle,proto3" json:"heapIdle,omitempty"` + HeapInuse uint64 `protobuf:"varint,8,opt,name=heapInuse,proto3" json:"heapInuse,omitempty"` + HeapReleased uint64 `protobuf:"varint,9,opt,name=heapReleased,proto3" json:"heapReleased,omitempty"` + HeapObjects uint64 `protobuf:"varint,10,opt,name=heapObjects,proto3" json:"heapObjects,omitempty"` + GcCPUFraction float64 `protobuf:"fixed64,11,opt,name=gcCPUFraction,proto3" json:"gcCPUFraction,omitempty"` unknownFields protoimpl.UnknownFields - - Alloc uint64 `protobuf:"varint,1,opt,name=alloc,proto3" json:"alloc,omitempty"` - TotalAlloc uint64 `protobuf:"varint,2,opt,name=totalAlloc,proto3" json:"totalAlloc,omitempty"` - Sys uint64 `protobuf:"varint,3,opt,name=sys,proto3" json:"sys,omitempty"` - NumGC uint32 `protobuf:"varint,4,opt,name=numGC,proto3" json:"numGC,omitempty"` - HeapAlloc uint64 `protobuf:"varint,5,opt,name=heapAlloc,proto3" json:"heapAlloc,omitempty"` - HeapSys uint64 `protobuf:"varint,6,opt,name=heapSys,proto3" json:"heapSys,omitempty"` - HeapIdle uint64 `protobuf:"varint,7,opt,name=heapIdle,proto3" json:"heapIdle,omitempty"` - HeapInuse uint64 `protobuf:"varint,8,opt,name=heapInuse,proto3" json:"heapInuse,omitempty"` - HeapReleased uint64 `protobuf:"varint,9,opt,name=heapReleased,proto3" json:"heapReleased,omitempty"` - HeapObjects uint64 `protobuf:"varint,10,opt,name=heapObjects,proto3" json:"heapObjects,omitempty"` - GcCPUFraction float64 `protobuf:"fixed64,11,opt,name=gcCPUFraction,proto3" json:"gcCPUFraction,omitempty"` + sizeCache protoimpl.SizeCache } func (x *HeapStats) Reset() { *x = HeapStats{} - if protoimpl.UnsafeEnabled { - mi := &file_debug_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_debug_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *HeapStats) String() string { @@ -145,7 +139,7 @@ func (*HeapStats) ProtoMessage() {} func (x *HeapStats) ProtoReflect() protoreflect.Message { mi := &file_debug_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -238,22 +232,19 @@ func (x *HeapStats) GetGcCPUFraction() float64 { } type HeapData struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Stats *HeapStats `protobuf:"bytes,1,opt,name=stats,proto3" json:"stats,omitempty"` + Objects []*HeapObject `protobuf:"bytes,2,rep,name=objects,proto3" json:"objects,omitempty"` + Edges []*HeapEdge `protobuf:"bytes,3,rep,name=edges,proto3" json:"edges,omitempty"` unknownFields protoimpl.UnknownFields - - Stats *HeapStats `protobuf:"bytes,1,opt,name=stats,proto3" json:"stats,omitempty"` - Objects []*HeapObject `protobuf:"bytes,2,rep,name=objects,proto3" json:"objects,omitempty"` - Edges []*HeapEdge `protobuf:"bytes,3,rep,name=edges,proto3" json:"edges,omitempty"` + sizeCache protoimpl.SizeCache } func (x *HeapData) Reset() { *x = HeapData{} - if protoimpl.UnsafeEnabled { - mi := &file_debug_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_debug_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *HeapData) String() string { @@ -264,7 +255,7 @@ func (*HeapData) ProtoMessage() {} func (x *HeapData) ProtoReflect() protoreflect.Message { mi := &file_debug_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -301,22 +292,19 @@ func (x *HeapData) GetEdges() []*HeapEdge { } type HeapEdge struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + From string `protobuf:"bytes,1,opt,name=from,proto3" json:"from,omitempty"` + To string `protobuf:"bytes,2,opt,name=to,proto3" json:"to,omitempty"` + FieldName string `protobuf:"bytes,3,opt,name=fieldName,proto3" json:"fieldName,omitempty"` unknownFields protoimpl.UnknownFields - - From string `protobuf:"bytes,1,opt,name=from,proto3" json:"from,omitempty"` - To string `protobuf:"bytes,2,opt,name=to,proto3" json:"to,omitempty"` - FieldName string `protobuf:"bytes,3,opt,name=fieldName,proto3" json:"fieldName,omitempty"` + sizeCache protoimpl.SizeCache } func (x *HeapEdge) Reset() { *x = HeapEdge{} - if protoimpl.UnsafeEnabled { - mi := &file_debug_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_debug_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *HeapEdge) String() string { @@ -327,7 +315,7 @@ func (*HeapEdge) ProtoMessage() {} func (x *HeapEdge) ProtoReflect() protoreflect.Message { mi := &file_debug_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -364,22 +352,19 @@ func (x *HeapEdge) GetFieldName() string { } type HeapResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + Data *HeapData `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` unknownFields protoimpl.UnknownFields - - Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` - Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` - Data *HeapData `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` + sizeCache protoimpl.SizeCache } func (x *HeapResponse) Reset() { *x = HeapResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_debug_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_debug_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *HeapResponse) String() string { @@ -390,7 +375,7 @@ func (*HeapResponse) ProtoMessage() {} func (x *HeapResponse) ProtoReflect() protoreflect.Message { mi := &file_debug_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -427,22 +412,19 @@ func (x *HeapResponse) GetData() *HeapData { } type HeapGraphResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + Data string `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` unknownFields protoimpl.UnknownFields - - Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` - Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` - Data string `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` + sizeCache protoimpl.SizeCache } func (x *HeapGraphResponse) Reset() { *x = HeapGraphResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_debug_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_debug_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *HeapGraphResponse) String() string { @@ -453,7 +435,7 @@ func (*HeapGraphResponse) ProtoMessage() {} func (x *HeapGraphResponse) ProtoReflect() protoreflect.Message { mi := &file_debug_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -489,6 +471,427 @@ func (x *HeapGraphResponse) GetData() string { return "" } +// CPU 采样响应数据 +type CpuResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + Data *CpuData `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CpuResponse) Reset() { + *x = CpuResponse{} + mi := &file_debug_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CpuResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CpuResponse) ProtoMessage() {} + +func (x *CpuResponse) ProtoReflect() protoreflect.Message { + mi := &file_debug_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CpuResponse.ProtoReflect.Descriptor instead. +func (*CpuResponse) Descriptor() ([]byte, []int) { + return file_debug_proto_rawDescGZIP(), []int{6} +} + +func (x *CpuResponse) GetCode() uint32 { + if x != nil { + return x.Code + } + return 0 +} + +func (x *CpuResponse) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *CpuResponse) GetData() *CpuData { + if x != nil { + return x.Data + } + return nil +} + +type CpuData struct { + state protoimpl.MessageState `protogen:"open.v1"` + TotalCpuTimeNs uint64 `protobuf:"varint,1,opt,name=total_cpu_time_ns,json=totalCpuTimeNs,proto3" json:"total_cpu_time_ns,omitempty"` // 总 CPU 时间(纳秒) + SamplingIntervalNs uint64 `protobuf:"varint,2,opt,name=sampling_interval_ns,json=samplingIntervalNs,proto3" json:"sampling_interval_ns,omitempty"` // 采样间隔(纳秒) + Functions []*FunctionProfile `protobuf:"bytes,3,rep,name=functions,proto3" json:"functions,omitempty"` // 函数调用栈信息 + Goroutines []*GoroutineProfile `protobuf:"bytes,4,rep,name=goroutines,proto3" json:"goroutines,omitempty"` // 协程信息 + SystemCalls []*SystemCall `protobuf:"bytes,5,rep,name=system_calls,json=systemCalls,proto3" json:"system_calls,omitempty"` // 系统调用信息 + RuntimeStats *RuntimeStats `protobuf:"bytes,6,opt,name=runtime_stats,json=runtimeStats,proto3" json:"runtime_stats,omitempty"` // 运行时统计信息 + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CpuData) Reset() { + *x = CpuData{} + mi := &file_debug_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CpuData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CpuData) ProtoMessage() {} + +func (x *CpuData) ProtoReflect() protoreflect.Message { + mi := &file_debug_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CpuData.ProtoReflect.Descriptor instead. +func (*CpuData) Descriptor() ([]byte, []int) { + return file_debug_proto_rawDescGZIP(), []int{7} +} + +func (x *CpuData) GetTotalCpuTimeNs() uint64 { + if x != nil { + return x.TotalCpuTimeNs + } + return 0 +} + +func (x *CpuData) GetSamplingIntervalNs() uint64 { + if x != nil { + return x.SamplingIntervalNs + } + return 0 +} + +func (x *CpuData) GetFunctions() []*FunctionProfile { + if x != nil { + return x.Functions + } + return nil +} + +func (x *CpuData) GetGoroutines() []*GoroutineProfile { + if x != nil { + return x.Goroutines + } + return nil +} + +func (x *CpuData) GetSystemCalls() []*SystemCall { + if x != nil { + return x.SystemCalls + } + return nil +} + +func (x *CpuData) GetRuntimeStats() *RuntimeStats { + if x != nil { + return x.RuntimeStats + } + return nil +} + +// 函数调用栈信息 +type FunctionProfile struct { + state protoimpl.MessageState `protogen:"open.v1"` + FunctionName string `protobuf:"bytes,1,opt,name=function_name,json=functionName,proto3" json:"function_name,omitempty"` // 函数名称 + CpuTimeNs uint64 `protobuf:"varint,2,opt,name=cpu_time_ns,json=cpuTimeNs,proto3" json:"cpu_time_ns,omitempty"` // 函数消耗的 CPU 时间(纳秒) + InvocationCount uint64 `protobuf:"varint,3,opt,name=invocation_count,json=invocationCount,proto3" json:"invocation_count,omitempty"` // 函数调用次数 + CallStack []string `protobuf:"bytes,4,rep,name=call_stack,json=callStack,proto3" json:"call_stack,omitempty"` // 调用栈(从调用者到被调用者) + IsInlined bool `protobuf:"varint,5,opt,name=is_inlined,json=isInlined,proto3" json:"is_inlined,omitempty"` // 是否是内联函数 + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *FunctionProfile) Reset() { + *x = FunctionProfile{} + mi := &file_debug_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FunctionProfile) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FunctionProfile) ProtoMessage() {} + +func (x *FunctionProfile) ProtoReflect() protoreflect.Message { + mi := &file_debug_proto_msgTypes[8] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FunctionProfile.ProtoReflect.Descriptor instead. +func (*FunctionProfile) Descriptor() ([]byte, []int) { + return file_debug_proto_rawDescGZIP(), []int{8} +} + +func (x *FunctionProfile) GetFunctionName() string { + if x != nil { + return x.FunctionName + } + return "" +} + +func (x *FunctionProfile) GetCpuTimeNs() uint64 { + if x != nil { + return x.CpuTimeNs + } + return 0 +} + +func (x *FunctionProfile) GetInvocationCount() uint64 { + if x != nil { + return x.InvocationCount + } + return 0 +} + +func (x *FunctionProfile) GetCallStack() []string { + if x != nil { + return x.CallStack + } + return nil +} + +func (x *FunctionProfile) GetIsInlined() bool { + if x != nil { + return x.IsInlined + } + return false +} + +// 协程信息 +type GoroutineProfile struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` // 协程 ID + State string `protobuf:"bytes,2,opt,name=state,proto3" json:"state,omitempty"` // 协程状态(如 running, blocked 等) + CpuTimeNs uint64 `protobuf:"varint,3,opt,name=cpu_time_ns,json=cpuTimeNs,proto3" json:"cpu_time_ns,omitempty"` // 协程消耗的 CPU 时间(纳秒) + CallStack []string `protobuf:"bytes,4,rep,name=call_stack,json=callStack,proto3" json:"call_stack,omitempty"` // 协程的调用栈 + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GoroutineProfile) Reset() { + *x = GoroutineProfile{} + mi := &file_debug_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GoroutineProfile) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GoroutineProfile) ProtoMessage() {} + +func (x *GoroutineProfile) ProtoReflect() protoreflect.Message { + mi := &file_debug_proto_msgTypes[9] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GoroutineProfile.ProtoReflect.Descriptor instead. +func (*GoroutineProfile) Descriptor() ([]byte, []int) { + return file_debug_proto_rawDescGZIP(), []int{9} +} + +func (x *GoroutineProfile) GetId() uint64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *GoroutineProfile) GetState() string { + if x != nil { + return x.State + } + return "" +} + +func (x *GoroutineProfile) GetCpuTimeNs() uint64 { + if x != nil { + return x.CpuTimeNs + } + return 0 +} + +func (x *GoroutineProfile) GetCallStack() []string { + if x != nil { + return x.CallStack + } + return nil +} + +// 系统调用信息 +type SystemCall struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // 系统调用名称 + CpuTimeNs uint64 `protobuf:"varint,2,opt,name=cpu_time_ns,json=cpuTimeNs,proto3" json:"cpu_time_ns,omitempty"` // 系统调用消耗的 CPU 时间(纳秒) + Count uint64 `protobuf:"varint,3,opt,name=count,proto3" json:"count,omitempty"` // 系统调用次数 + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SystemCall) Reset() { + *x = SystemCall{} + mi := &file_debug_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SystemCall) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SystemCall) ProtoMessage() {} + +func (x *SystemCall) ProtoReflect() protoreflect.Message { + mi := &file_debug_proto_msgTypes[10] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SystemCall.ProtoReflect.Descriptor instead. +func (*SystemCall) Descriptor() ([]byte, []int) { + return file_debug_proto_rawDescGZIP(), []int{10} +} + +func (x *SystemCall) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *SystemCall) GetCpuTimeNs() uint64 { + if x != nil { + return x.CpuTimeNs + } + return 0 +} + +func (x *SystemCall) GetCount() uint64 { + if x != nil { + return x.Count + } + return 0 +} + +// 运行时统计信息 +type RuntimeStats struct { + state protoimpl.MessageState `protogen:"open.v1"` + GcCpuFraction float64 `protobuf:"fixed64,1,opt,name=gc_cpu_fraction,json=gcCpuFraction,proto3" json:"gc_cpu_fraction,omitempty"` // 垃圾回收占用的 CPU 时间比例 + GcCount uint64 `protobuf:"varint,2,opt,name=gc_count,json=gcCount,proto3" json:"gc_count,omitempty"` // 垃圾回收次数 + GcPauseTimeNs uint64 `protobuf:"varint,3,opt,name=gc_pause_time_ns,json=gcPauseTimeNs,proto3" json:"gc_pause_time_ns,omitempty"` // 垃圾回收暂停时间(纳秒) + BlockingTimeNs uint64 `protobuf:"varint,4,opt,name=blocking_time_ns,json=blockingTimeNs,proto3" json:"blocking_time_ns,omitempty"` // 阻塞时间(纳秒) + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RuntimeStats) Reset() { + *x = RuntimeStats{} + mi := &file_debug_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RuntimeStats) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RuntimeStats) ProtoMessage() {} + +func (x *RuntimeStats) ProtoReflect() protoreflect.Message { + mi := &file_debug_proto_msgTypes[11] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RuntimeStats.ProtoReflect.Descriptor instead. +func (*RuntimeStats) Descriptor() ([]byte, []int) { + return file_debug_proto_rawDescGZIP(), []int{11} +} + +func (x *RuntimeStats) GetGcCpuFraction() float64 { + if x != nil { + return x.GcCpuFraction + } + return 0 +} + +func (x *RuntimeStats) GetGcCount() uint64 { + if x != nil { + return x.GcCount + } + return 0 +} + +func (x *RuntimeStats) GetGcPauseTimeNs() uint64 { + if x != nil { + return x.GcPauseTimeNs + } + return 0 +} + +func (x *RuntimeStats) GetBlockingTimeNs() uint64 { + if x != nil { + return x.BlockingTimeNs + } + return 0 +} + var File_debug_proto protoreflect.FileDescriptor var file_debug_proto_rawDesc = []byte{ @@ -554,21 +957,88 @@ var file_debug_proto_rawDesc = []byte{ 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, - 0x74, 0x61, 0x32, 0xb7, 0x01, 0x0a, 0x03, 0x61, 0x70, 0x69, 0x12, 0x4f, 0x0a, 0x07, 0x47, 0x65, - 0x74, 0x48, 0x65, 0x61, 0x70, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x13, 0x2e, - 0x64, 0x65, 0x62, 0x75, 0x67, 0x2e, 0x48, 0x65, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x17, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x11, 0x12, 0x0f, 0x2f, 0x64, 0x65, 0x62, - 0x75, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x68, 0x65, 0x61, 0x70, 0x12, 0x5f, 0x0a, 0x0c, 0x47, - 0x65, 0x74, 0x48, 0x65, 0x61, 0x70, 0x47, 0x72, 0x61, 0x70, 0x68, 0x12, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x1a, 0x18, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2e, 0x48, 0x65, 0x61, 0x70, - 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1d, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2f, 0x61, 0x70, - 0x69, 0x2f, 0x68, 0x65, 0x61, 0x70, 0x2f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x42, 0x1d, 0x5a, 0x1b, - 0x6d, 0x37, 0x73, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x6c, 0x75, 0x67, - 0x69, 0x6e, 0x2f, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x74, 0x61, 0x22, 0x5f, 0x0a, 0x0b, 0x43, 0x70, 0x75, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, + 0x22, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, + 0x64, 0x65, 0x62, 0x75, 0x67, 0x2e, 0x43, 0x70, 0x75, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x22, 0xc5, 0x02, 0x0a, 0x07, 0x43, 0x70, 0x75, 0x44, 0x61, 0x74, 0x61, 0x12, + 0x29, 0x0a, 0x11, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x63, 0x70, 0x75, 0x5f, 0x74, 0x69, 0x6d, + 0x65, 0x5f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x74, 0x6f, 0x74, 0x61, + 0x6c, 0x43, 0x70, 0x75, 0x54, 0x69, 0x6d, 0x65, 0x4e, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x61, + 0x6d, 0x70, 0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, + 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x69, + 0x6e, 0x67, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x4e, 0x73, 0x12, 0x34, 0x0a, 0x09, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x16, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x12, 0x37, 0x0a, 0x0a, 0x67, 0x6f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x73, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2e, 0x47, + 0x6f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, + 0x0a, 0x67, 0x6f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x0c, 0x73, + 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x11, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x0b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x43, 0x61, 0x6c, 0x6c, + 0x73, 0x12, 0x38, 0x0a, 0x0d, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73, 0x74, 0x61, + 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, + 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x0c, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x22, 0xbf, 0x01, 0x0a, 0x0f, + 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, + 0x23, 0x0a, 0x0d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0b, 0x63, 0x70, 0x75, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x5f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x63, 0x70, 0x75, 0x54, 0x69, + 0x6d, 0x65, 0x4e, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, + 0x69, 0x6e, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, + 0x1d, 0x0a, 0x0a, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x09, 0x63, 0x61, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x12, 0x1d, + 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x49, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x64, 0x22, 0x77, 0x0a, + 0x10, 0x47, 0x6f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, + 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1e, 0x0a, 0x0b, 0x63, 0x70, 0x75, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x5f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x63, 0x70, + 0x75, 0x54, 0x69, 0x6d, 0x65, 0x4e, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x61, 0x6c, 0x6c, 0x5f, + 0x73, 0x74, 0x61, 0x63, 0x6b, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x63, 0x61, 0x6c, + 0x6c, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x22, 0x56, 0x0a, 0x0a, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x43, 0x61, 0x6c, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0b, 0x63, 0x70, 0x75, 0x5f, + 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x63, + 0x70, 0x75, 0x54, 0x69, 0x6d, 0x65, 0x4e, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xa4, + 0x01, 0x0a, 0x0c, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, + 0x26, 0x0a, 0x0f, 0x67, 0x63, 0x5f, 0x63, 0x70, 0x75, 0x5f, 0x66, 0x72, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0d, 0x67, 0x63, 0x43, 0x70, 0x75, 0x46, + 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x63, 0x5f, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x67, 0x63, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x10, 0x67, 0x63, 0x5f, 0x70, 0x61, 0x75, 0x73, 0x65, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x5f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x67, 0x63, + 0x50, 0x61, 0x75, 0x73, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x4e, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6e, 0x73, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x54, + 0x69, 0x6d, 0x65, 0x4e, 0x73, 0x32, 0x85, 0x02, 0x0a, 0x03, 0x61, 0x70, 0x69, 0x12, 0x4f, 0x0a, + 0x07, 0x47, 0x65, 0x74, 0x48, 0x65, 0x61, 0x70, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x1a, 0x13, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2e, 0x48, 0x65, 0x61, 0x70, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x17, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x11, 0x12, 0x0f, 0x2f, + 0x64, 0x65, 0x62, 0x75, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x68, 0x65, 0x61, 0x70, 0x12, 0x5f, + 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x48, 0x65, 0x61, 0x70, 0x47, 0x72, 0x61, 0x70, 0x68, 0x12, 0x16, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x18, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2e, 0x48, + 0x65, 0x61, 0x70, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x64, 0x65, 0x62, 0x75, 0x67, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x68, 0x65, 0x61, 0x70, 0x2f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x12, + 0x4c, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x43, 0x70, 0x75, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x1a, 0x12, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2e, 0x43, 0x70, 0x75, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x12, 0x0e, 0x2f, + 0x64, 0x65, 0x62, 0x75, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x70, 0x75, 0x42, 0x1d, 0x5a, + 0x1b, 0x6d, 0x37, 0x73, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x2f, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -583,30 +1053,43 @@ func file_debug_proto_rawDescGZIP() []byte { return file_debug_proto_rawDescData } -var file_debug_proto_msgTypes = make([]protoimpl.MessageInfo, 6) -var file_debug_proto_goTypes = []interface{}{ +var file_debug_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_debug_proto_goTypes = []any{ (*HeapObject)(nil), // 0: debug.HeapObject (*HeapStats)(nil), // 1: debug.HeapStats (*HeapData)(nil), // 2: debug.HeapData (*HeapEdge)(nil), // 3: debug.HeapEdge (*HeapResponse)(nil), // 4: debug.HeapResponse (*HeapGraphResponse)(nil), // 5: debug.HeapGraphResponse - (*emptypb.Empty)(nil), // 6: google.protobuf.Empty + (*CpuResponse)(nil), // 6: debug.CpuResponse + (*CpuData)(nil), // 7: debug.CpuData + (*FunctionProfile)(nil), // 8: debug.FunctionProfile + (*GoroutineProfile)(nil), // 9: debug.GoroutineProfile + (*SystemCall)(nil), // 10: debug.SystemCall + (*RuntimeStats)(nil), // 11: debug.RuntimeStats + (*emptypb.Empty)(nil), // 12: google.protobuf.Empty } var file_debug_proto_depIdxs = []int32{ - 1, // 0: debug.HeapData.stats:type_name -> debug.HeapStats - 0, // 1: debug.HeapData.objects:type_name -> debug.HeapObject - 3, // 2: debug.HeapData.edges:type_name -> debug.HeapEdge - 2, // 3: debug.HeapResponse.data:type_name -> debug.HeapData - 6, // 4: debug.api.GetHeap:input_type -> google.protobuf.Empty - 6, // 5: debug.api.GetHeapGraph:input_type -> google.protobuf.Empty - 4, // 6: debug.api.GetHeap:output_type -> debug.HeapResponse - 5, // 7: debug.api.GetHeapGraph:output_type -> debug.HeapGraphResponse - 6, // [6:8] is the sub-list for method output_type - 4, // [4:6] is the sub-list for method input_type - 4, // [4:4] is the sub-list for extension type_name - 4, // [4:4] is the sub-list for extension extendee - 0, // [0:4] is the sub-list for field type_name + 1, // 0: debug.HeapData.stats:type_name -> debug.HeapStats + 0, // 1: debug.HeapData.objects:type_name -> debug.HeapObject + 3, // 2: debug.HeapData.edges:type_name -> debug.HeapEdge + 2, // 3: debug.HeapResponse.data:type_name -> debug.HeapData + 7, // 4: debug.CpuResponse.data:type_name -> debug.CpuData + 8, // 5: debug.CpuData.functions:type_name -> debug.FunctionProfile + 9, // 6: debug.CpuData.goroutines:type_name -> debug.GoroutineProfile + 10, // 7: debug.CpuData.system_calls:type_name -> debug.SystemCall + 11, // 8: debug.CpuData.runtime_stats:type_name -> debug.RuntimeStats + 12, // 9: debug.api.GetHeap:input_type -> google.protobuf.Empty + 12, // 10: debug.api.GetHeapGraph:input_type -> google.protobuf.Empty + 12, // 11: debug.api.GetCpu:input_type -> google.protobuf.Empty + 4, // 12: debug.api.GetHeap:output_type -> debug.HeapResponse + 5, // 13: debug.api.GetHeapGraph:output_type -> debug.HeapGraphResponse + 6, // 14: debug.api.GetCpu:output_type -> debug.CpuResponse + 12, // [12:15] is the sub-list for method output_type + 9, // [9:12] is the sub-list for method input_type + 9, // [9:9] is the sub-list for extension type_name + 9, // [9:9] is the sub-list for extension extendee + 0, // [0:9] is the sub-list for field type_name } func init() { file_debug_proto_init() } @@ -614,87 +1097,13 @@ func file_debug_proto_init() { if File_debug_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_debug_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HeapObject); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_debug_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HeapStats); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_debug_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HeapData); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_debug_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HeapEdge); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_debug_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HeapResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_debug_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HeapGraphResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_debug_proto_rawDesc, NumEnums: 0, - NumMessages: 6, + NumMessages: 12, NumExtensions: 0, NumServices: 1, }, diff --git a/plugin/debug/pb/debug.pb.gw.go b/plugin/debug/pb/debug.pb.gw.go index 65bbb15a..1a8e3bd6 100644 --- a/plugin/debug/pb/debug.pb.gw.go +++ b/plugin/debug/pb/debug.pb.gw.go @@ -10,6 +10,7 @@ package pb import ( "context" + "errors" "io" "net/http" @@ -25,64 +26,83 @@ import ( ) // Suppress "imported and not used" errors -var _ codes.Code -var _ io.Reader -var _ status.Status -var _ = runtime.String -var _ = utilities.NewDoubleArray -var _ = metadata.Join +var ( + _ codes.Code + _ io.Reader + _ status.Status + _ = errors.New + _ = runtime.String + _ = utilities.NewDoubleArray + _ = metadata.Join +) func request_Api_GetHeap_0(ctx context.Context, marshaler runtime.Marshaler, client ApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq emptypb.Empty - var metadata runtime.ServerMetadata - + var ( + protoReq emptypb.Empty + metadata runtime.ServerMetadata + ) msg, err := client.GetHeap(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err - } func local_request_Api_GetHeap_0(ctx context.Context, marshaler runtime.Marshaler, server ApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq emptypb.Empty - var metadata runtime.ServerMetadata - + var ( + protoReq emptypb.Empty + metadata runtime.ServerMetadata + ) msg, err := server.GetHeap(ctx, &protoReq) return msg, metadata, err - } func request_Api_GetHeapGraph_0(ctx context.Context, marshaler runtime.Marshaler, client ApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq emptypb.Empty - var metadata runtime.ServerMetadata - + var ( + protoReq emptypb.Empty + metadata runtime.ServerMetadata + ) msg, err := client.GetHeapGraph(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err - } func local_request_Api_GetHeapGraph_0(ctx context.Context, marshaler runtime.Marshaler, server ApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq emptypb.Empty - var metadata runtime.ServerMetadata - + var ( + protoReq emptypb.Empty + metadata runtime.ServerMetadata + ) msg, err := server.GetHeapGraph(ctx, &protoReq) return msg, metadata, err +} +func request_Api_GetCpu_0(ctx context.Context, marshaler runtime.Marshaler, client ApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq emptypb.Empty + metadata runtime.ServerMetadata + ) + msg, err := client.GetCpu(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err +} + +func local_request_Api_GetCpu_0(ctx context.Context, marshaler runtime.Marshaler, server ApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq emptypb.Empty + metadata runtime.ServerMetadata + ) + msg, err := server.GetCpu(ctx, &protoReq) + return msg, metadata, err } // RegisterApiHandlerServer registers the http handlers for service Api to "mux". // UnaryRPC :call ApiServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. // Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterApiHandlerFromEndpoint instead. +// GRPC interceptors will not work for this type of registration. To use interceptors, you must use the "runtime.WithMiddlewares" option in the "runtime.NewServeMux" call. func RegisterApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, server ApiServer) error { - - mux.Handle("GET", pattern_Api_GetHeap_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle(http.MethodGet, pattern_Api_GetHeap_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - var err error - var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/debug.Api/GetHeap", runtime.WithHTTPPathPattern("/debug/api/heap")) + annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/debug.Api/GetHeap", runtime.WithHTTPPathPattern("/debug/api/heap")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -94,20 +114,15 @@ func RegisterApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, server runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_Api_GetHeap_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - }) - - mux.Handle("GET", pattern_Api_GetHeapGraph_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle(http.MethodGet, pattern_Api_GetHeapGraph_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - var err error - var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/debug.Api/GetHeapGraph", runtime.WithHTTPPathPattern("/debug/api/heap/graph")) + annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/debug.Api/GetHeapGraph", runtime.WithHTTPPathPattern("/debug/api/heap/graph")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -119,9 +134,27 @@ func RegisterApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, server runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_Api_GetHeapGraph_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - + }) + mux.Handle(http.MethodGet, pattern_Api_GetCpu_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/debug.Api/GetCpu", runtime.WithHTTPPathPattern("/debug/api/cpu")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Api_GetCpu_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_Api_GetCpu_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) return nil @@ -130,25 +163,24 @@ func RegisterApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, server // RegisterApiHandlerFromEndpoint is same as RegisterApiHandler but // automatically dials to "endpoint" and closes the connection when "ctx" gets done. func RegisterApiHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { - conn, err := grpc.DialContext(ctx, endpoint, opts...) + conn, err := grpc.NewClient(endpoint, opts...) if err != nil { return err } defer func() { if err != nil { if cerr := conn.Close(); cerr != nil { - grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr) } return } go func() { <-ctx.Done() if cerr := conn.Close(); cerr != nil { - grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr) } }() }() - return RegisterApiHandler(ctx, mux, conn) } @@ -162,16 +194,13 @@ func RegisterApiHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.C // to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "ApiClient". // Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "ApiClient" // doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in -// "ApiClient" to call the correct interceptors. +// "ApiClient" to call the correct interceptors. This client ignores the HTTP middlewares. func RegisterApiHandlerClient(ctx context.Context, mux *runtime.ServeMux, client ApiClient) error { - - mux.Handle("GET", pattern_Api_GetHeap_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle(http.MethodGet, pattern_Api_GetHeap_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - var err error - var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/debug.Api/GetHeap", runtime.WithHTTPPathPattern("/debug/api/heap")) + annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/debug.Api/GetHeap", runtime.WithHTTPPathPattern("/debug/api/heap")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -182,18 +211,13 @@ func RegisterApiHandlerClient(ctx context.Context, mux *runtime.ServeMux, client runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_Api_GetHeap_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - }) - - mux.Handle("GET", pattern_Api_GetHeapGraph_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle(http.MethodGet, pattern_Api_GetHeapGraph_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - var err error - var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/debug.Api/GetHeapGraph", runtime.WithHTTPPathPattern("/debug/api/heap/graph")) + annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/debug.Api/GetHeapGraph", runtime.WithHTTPPathPattern("/debug/api/heap/graph")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -204,22 +228,36 @@ func RegisterApiHandlerClient(ctx context.Context, mux *runtime.ServeMux, client runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_Api_GetHeapGraph_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - }) - + mux.Handle(http.MethodGet, pattern_Api_GetCpu_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/debug.Api/GetCpu", runtime.WithHTTPPathPattern("/debug/api/cpu")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Api_GetCpu_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_Api_GetCpu_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) return nil } var ( - pattern_Api_GetHeap_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"debug", "api", "heap"}, "")) - + pattern_Api_GetHeap_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"debug", "api", "heap"}, "")) pattern_Api_GetHeapGraph_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"debug", "api", "heap", "graph"}, "")) + pattern_Api_GetCpu_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"debug", "api", "cpu"}, "")) ) var ( - forward_Api_GetHeap_0 = runtime.ForwardResponseMessage - + forward_Api_GetHeap_0 = runtime.ForwardResponseMessage forward_Api_GetHeapGraph_0 = runtime.ForwardResponseMessage + forward_Api_GetCpu_0 = runtime.ForwardResponseMessage ) diff --git a/plugin/debug/pb/debug.proto b/plugin/debug/pb/debug.proto index 1d1b7657..2ad1063b 100644 --- a/plugin/debug/pb/debug.proto +++ b/plugin/debug/pb/debug.proto @@ -16,6 +16,11 @@ service api { get: "/debug/api/heap/graph" }; } + rpc GetCpu (google.protobuf.Empty) returns (CpuResponse) { + option (google.api.http) = { + get: "/debug/api/cpu" + }; + } } message HeapObject { @@ -64,3 +69,50 @@ message HeapGraphResponse { string message = 2; string data = 3; } + +// CPU 采样响应数据 +message CpuResponse { + uint32 code = 1; + string message = 2; + CpuData data = 3; +} + +message CpuData { + uint64 total_cpu_time_ns = 1; // 总 CPU 时间(纳秒) + uint64 sampling_interval_ns = 2; // 采样间隔(纳秒) + repeated FunctionProfile functions = 3; // 函数调用栈信息 + repeated GoroutineProfile goroutines = 4; // 协程信息 + repeated SystemCall system_calls = 5; // 系统调用信息 + RuntimeStats runtime_stats = 6; // 运行时统计信息 +} + +// 函数调用栈信息 +message FunctionProfile { + string function_name = 1; // 函数名称 + uint64 cpu_time_ns = 2; // 函数消耗的 CPU 时间(纳秒) + uint64 invocation_count = 3; // 函数调用次数 + repeated string call_stack = 4; // 调用栈(从调用者到被调用者) + bool is_inlined = 5; // 是否是内联函数 +} +// 协程信息 +message GoroutineProfile { + uint64 id = 1; // 协程 ID + string state = 2; // 协程状态(如 running, blocked 等) + uint64 cpu_time_ns = 3; // 协程消耗的 CPU 时间(纳秒) + repeated string call_stack = 4; // 协程的调用栈 +} + +// 系统调用信息 +message SystemCall { + string name = 1; // 系统调用名称 + uint64 cpu_time_ns = 2; // 系统调用消耗的 CPU 时间(纳秒) + uint64 count = 3; // 系统调用次数 +} + +// 运行时统计信息 +message RuntimeStats { + double gc_cpu_fraction = 1; // 垃圾回收占用的 CPU 时间比例 + uint64 gc_count = 2; // 垃圾回收次数 + uint64 gc_pause_time_ns = 3; // 垃圾回收暂停时间(纳秒) + uint64 blocking_time_ns = 4; // 阻塞时间(纳秒) +} \ No newline at end of file diff --git a/plugin/debug/pb/debug_grpc.pb.go b/plugin/debug/pb/debug_grpc.pb.go index 2cccf1fd..2b0ce1ca 100644 --- a/plugin/debug/pb/debug_grpc.pb.go +++ b/plugin/debug/pb/debug_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.2.0 -// - protoc v3.19.1 +// - protoc-gen-go-grpc v1.5.1 +// - protoc v5.29.1 // source: debug.proto package pb @@ -16,8 +16,14 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + Api_GetHeap_FullMethodName = "/debug.api/GetHeap" + Api_GetHeapGraph_FullMethodName = "/debug.api/GetHeapGraph" + Api_GetCpu_FullMethodName = "/debug.api/GetCpu" +) // ApiClient is the client API for Api service. // @@ -25,6 +31,7 @@ const _ = grpc.SupportPackageIsVersion7 type ApiClient interface { GetHeap(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*HeapResponse, error) GetHeapGraph(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*HeapGraphResponse, error) + GetCpu(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*CpuResponse, error) } type apiClient struct { @@ -36,8 +43,9 @@ func NewApiClient(cc grpc.ClientConnInterface) ApiClient { } func (c *apiClient) GetHeap(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*HeapResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(HeapResponse) - err := c.cc.Invoke(ctx, "/debug.api/GetHeap", in, out, opts...) + err := c.cc.Invoke(ctx, Api_GetHeap_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -45,8 +53,19 @@ func (c *apiClient) GetHeap(ctx context.Context, in *emptypb.Empty, opts ...grpc } func (c *apiClient) GetHeapGraph(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*HeapGraphResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(HeapGraphResponse) - err := c.cc.Invoke(ctx, "/debug.api/GetHeapGraph", in, out, opts...) + err := c.cc.Invoke(ctx, Api_GetHeapGraph_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *apiClient) GetCpu(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*CpuResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(CpuResponse) + err := c.cc.Invoke(ctx, Api_GetCpu_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -55,16 +74,20 @@ func (c *apiClient) GetHeapGraph(ctx context.Context, in *emptypb.Empty, opts .. // ApiServer is the server API for Api service. // All implementations must embed UnimplementedApiServer -// for forward compatibility +// for forward compatibility. type ApiServer interface { GetHeap(context.Context, *emptypb.Empty) (*HeapResponse, error) GetHeapGraph(context.Context, *emptypb.Empty) (*HeapGraphResponse, error) + GetCpu(context.Context, *emptypb.Empty) (*CpuResponse, error) mustEmbedUnimplementedApiServer() } -// UnimplementedApiServer must be embedded to have forward compatible implementations. -type UnimplementedApiServer struct { -} +// UnimplementedApiServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedApiServer struct{} func (UnimplementedApiServer) GetHeap(context.Context, *emptypb.Empty) (*HeapResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetHeap not implemented") @@ -72,7 +95,11 @@ func (UnimplementedApiServer) GetHeap(context.Context, *emptypb.Empty) (*HeapRes func (UnimplementedApiServer) GetHeapGraph(context.Context, *emptypb.Empty) (*HeapGraphResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetHeapGraph not implemented") } +func (UnimplementedApiServer) GetCpu(context.Context, *emptypb.Empty) (*CpuResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetCpu not implemented") +} func (UnimplementedApiServer) mustEmbedUnimplementedApiServer() {} +func (UnimplementedApiServer) testEmbeddedByValue() {} // UnsafeApiServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to ApiServer will @@ -82,6 +109,13 @@ type UnsafeApiServer interface { } func RegisterApiServer(s grpc.ServiceRegistrar, srv ApiServer) { + // If the following call pancis, it indicates UnimplementedApiServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&Api_ServiceDesc, srv) } @@ -95,7 +129,7 @@ func _Api_GetHeap_Handler(srv interface{}, ctx context.Context, dec func(interfa } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/debug.api/GetHeap", + FullMethod: Api_GetHeap_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ApiServer).GetHeap(ctx, req.(*emptypb.Empty)) @@ -113,7 +147,7 @@ func _Api_GetHeapGraph_Handler(srv interface{}, ctx context.Context, dec func(in } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/debug.api/GetHeapGraph", + FullMethod: Api_GetHeapGraph_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ApiServer).GetHeapGraph(ctx, req.(*emptypb.Empty)) @@ -121,6 +155,24 @@ func _Api_GetHeapGraph_Handler(srv interface{}, ctx context.Context, dec func(in return interceptor(ctx, in, info, handler) } +func _Api_GetCpu_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ApiServer).GetCpu(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Api_GetCpu_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ApiServer).GetCpu(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + // Api_ServiceDesc is the grpc.ServiceDesc for Api service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -136,6 +188,10 @@ var Api_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetHeapGraph", Handler: _Api_GetHeapGraph_Handler, }, + { + MethodName: "GetCpu", + Handler: _Api_GetCpu_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "debug.proto",