diff --git a/api/proto/agent_master/yagpcc_action_service.pb.go b/api/proto/agent_master/yagpcc_action_service.pb.go index a2c21ee..cc30b21 100644 --- a/api/proto/agent_master/yagpcc_action_service.pb.go +++ b/api/proto/agent_master/yagpcc_action_service.pb.go @@ -1,16 +1,16 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.36.11 -// protoc v3.12.4 +// protoc v6.33.4 // source: api/proto/agent_master/yagpcc_action_service.proto package greenplum import ( - empty "github.com/golang/protobuf/ptypes/empty" common "github.com/open-gpdb/yagpcc/api/proto/common" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" reflect "reflect" sync "sync" unsafe "unsafe" @@ -426,7 +426,7 @@ var file_api_proto_agent_master_yagpcc_action_service_proto_goTypes = []any{ (*TerminateSessionsRequest)(nil), // 6: yagpcc.TerminateSessionsRequest (*common.QueryKey)(nil), // 7: yagpcc.QueryKey (*common.SessionKey)(nil), // 8: yagpcc.SessionKey - (*empty.Empty)(nil), // 9: google.protobuf.Empty + (*emptypb.Empty)(nil), // 9: google.protobuf.Empty } var file_api_proto_agent_master_yagpcc_action_service_proto_depIdxs = []int32{ 7, // 0: yagpcc.MoveQueryToResourceGroupRequest.query_key:type_name -> yagpcc.QueryKey diff --git a/api/proto/agent_master/yagpcc_action_service_grpc.pb.go b/api/proto/agent_master/yagpcc_action_service_grpc.pb.go index abda8c7..4062b06 100644 --- a/api/proto/agent_master/yagpcc_action_service_grpc.pb.go +++ b/api/proto/agent_master/yagpcc_action_service_grpc.pb.go @@ -1,17 +1,17 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.6.1 -// - protoc v3.12.4 +// - protoc v6.33.4 // source: api/proto/agent_master/yagpcc_action_service.proto package greenplum import ( context "context" - empty "github.com/golang/protobuf/ptypes/empty" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" ) // This is a compile-time assertion to ensure that this generated file @@ -30,7 +30,7 @@ const ( // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type ActionServiceClient interface { - MoveQueryToResourceGroup(ctx context.Context, in *MoveQueryToResourceGroupRequest, opts ...grpc.CallOption) (*empty.Empty, error) + MoveQueryToResourceGroup(ctx context.Context, in *MoveQueryToResourceGroupRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) TerminateQuery(ctx context.Context, in *TerminateQueryRequest, opts ...grpc.CallOption) (*TerminateResponse, error) TerminateSession(ctx context.Context, in *TerminateSessionRequest, opts ...grpc.CallOption) (*TerminateResponse, error) TerminateSessions(ctx context.Context, in *TerminateSessionsRequest, opts ...grpc.CallOption) (*TerminateResponses, error) @@ -44,9 +44,9 @@ func NewActionServiceClient(cc grpc.ClientConnInterface) ActionServiceClient { return &actionServiceClient{cc} } -func (c *actionServiceClient) MoveQueryToResourceGroup(ctx context.Context, in *MoveQueryToResourceGroupRequest, opts ...grpc.CallOption) (*empty.Empty, error) { +func (c *actionServiceClient) MoveQueryToResourceGroup(ctx context.Context, in *MoveQueryToResourceGroupRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(empty.Empty) + out := new(emptypb.Empty) err := c.cc.Invoke(ctx, ActionService_MoveQueryToResourceGroup_FullMethodName, in, out, cOpts...) if err != nil { return nil, err @@ -88,7 +88,7 @@ func (c *actionServiceClient) TerminateSessions(ctx context.Context, in *Termina // All implementations must embed UnimplementedActionServiceServer // for forward compatibility. type ActionServiceServer interface { - MoveQueryToResourceGroup(context.Context, *MoveQueryToResourceGroupRequest) (*empty.Empty, error) + MoveQueryToResourceGroup(context.Context, *MoveQueryToResourceGroupRequest) (*emptypb.Empty, error) TerminateQuery(context.Context, *TerminateQueryRequest) (*TerminateResponse, error) TerminateSession(context.Context, *TerminateSessionRequest) (*TerminateResponse, error) TerminateSessions(context.Context, *TerminateSessionsRequest) (*TerminateResponses, error) @@ -102,7 +102,7 @@ type ActionServiceServer interface { // pointer dereference when methods are called. type UnimplementedActionServiceServer struct{} -func (UnimplementedActionServiceServer) MoveQueryToResourceGroup(context.Context, *MoveQueryToResourceGroupRequest) (*empty.Empty, error) { +func (UnimplementedActionServiceServer) MoveQueryToResourceGroup(context.Context, *MoveQueryToResourceGroupRequest) (*emptypb.Empty, error) { return nil, status.Error(codes.Unimplemented, "method MoveQueryToResourceGroup not implemented") } func (UnimplementedActionServiceServer) TerminateQuery(context.Context, *TerminateQueryRequest) (*TerminateResponse, error) { diff --git a/api/proto/agent_master/yagpcc_get_service.pb.go b/api/proto/agent_master/yagpcc_get_service.pb.go index 8b9bc46..f0f3d3a 100644 --- a/api/proto/agent_master/yagpcc_get_service.pb.go +++ b/api/proto/agent_master/yagpcc_get_service.pb.go @@ -1,16 +1,16 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.36.11 -// protoc v3.12.4 +// protoc v6.33.4 // source: api/proto/agent_master/yagpcc_get_service.proto package greenplum import ( - timestamp "github.com/golang/protobuf/ptypes/timestamp" common "github.com/open-gpdb/yagpcc/api/proto/common" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" unsafe "unsafe" @@ -1525,13 +1525,13 @@ type QueryStat struct { state protoimpl.MessageState `protogen:"open.v1"` ClusterId string `protobuf:"bytes,1,opt,name=cluster_id,json=clusterId,proto3" json:"cluster_id,omitempty"` Hostname string `protobuf:"bytes,2,opt,name=hostname,proto3" json:"hostname,omitempty"` - CollectTime *timestamp.Timestamp `protobuf:"bytes,3,opt,name=collect_time,json=collectTime,proto3" json:"collect_time,omitempty"` + CollectTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=collect_time,json=collectTime,proto3" json:"collect_time,omitempty"` QueryKey *common.QueryKey `protobuf:"bytes,4,opt,name=query_key,json=queryKey,proto3" json:"query_key,omitempty"` QueryInfo *common.QueryInfo `protobuf:"bytes,5,opt,name=query_info,json=queryInfo,proto3" json:"query_info,omitempty"` StatKind StatKind `protobuf:"varint,6,opt,name=stat_kind,json=statKind,proto3,enum=yagpcc.StatKind" json:"stat_kind,omitempty"` QueryStatus common.QueryStatus `protobuf:"varint,7,opt,name=query_status,json=queryStatus,proto3,enum=yagpcc.QueryStatus" json:"query_status,omitempty"` - StartTime *timestamp.Timestamp `protobuf:"bytes,8,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` - EndTime *timestamp.Timestamp `protobuf:"bytes,9,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"` + StartTime *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` + EndTime *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"` Completed bool `protobuf:"varint,10,opt,name=completed,proto3" json:"completed,omitempty"` // query completed or not TotalQueryMetrics *common.GPMetrics `protobuf:"bytes,11,opt,name=total_query_metrics,json=totalQueryMetrics,proto3" json:"total_query_metrics,omitempty"` // query metrics calculated as sum from segments AggregatedMetrics *common.AggregatedMetrics `protobuf:"bytes,12,opt,name=aggregated_metrics,json=aggregatedMetrics,proto3" json:"aggregated_metrics,omitempty"` // set if stat_kind == SK_AGGREGATED - for short queries @@ -1590,7 +1590,7 @@ func (x *QueryStat) GetHostname() string { return "" } -func (x *QueryStat) GetCollectTime() *timestamp.Timestamp { +func (x *QueryStat) GetCollectTime() *timestamppb.Timestamp { if x != nil { return x.CollectTime } @@ -1625,14 +1625,14 @@ func (x *QueryStat) GetQueryStatus() common.QueryStatus { return common.QueryStatus(0) } -func (x *QueryStat) GetStartTime() *timestamp.Timestamp { +func (x *QueryStat) GetStartTime() *timestamppb.Timestamp { if x != nil { return x.StartTime } return nil } -func (x *QueryStat) GetEndTime() *timestamp.Timestamp { +func (x *QueryStat) GetEndTime() *timestamppb.Timestamp { if x != nil { return x.EndTime } @@ -1901,11 +1901,11 @@ type SegmentMetrics struct { state protoimpl.MessageState `protogen:"open.v1"` ClusterId string `protobuf:"bytes,1,opt,name=cluster_id,json=clusterId,proto3" json:"cluster_id,omitempty"` Hostname string `protobuf:"bytes,2,opt,name=hostname,proto3" json:"hostname,omitempty"` - CollectTime *timestamp.Timestamp `protobuf:"bytes,3,opt,name=collect_time,json=collectTime,proto3" json:"collect_time,omitempty"` + CollectTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=collect_time,json=collectTime,proto3" json:"collect_time,omitempty"` SegmentKey *common.SegmentKey `protobuf:"bytes,4,opt,name=segment_key,json=segmentKey,proto3" json:"segment_key,omitempty"` QueryStatus common.QueryStatus `protobuf:"varint,6,opt,name=query_status,json=queryStatus,proto3,enum=yagpcc.QueryStatus" json:"query_status,omitempty"` - StartTime *timestamp.Timestamp `protobuf:"bytes,7,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` - EndTime *timestamp.Timestamp `protobuf:"bytes,8,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"` + StartTime *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` + EndTime *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"` SegmentMetrics *common.GPMetrics `protobuf:"bytes,9,opt,name=segment_metrics,json=segmentMetrics,proto3" json:"segment_metrics,omitempty"` QueryKey *common.QueryKey `protobuf:"bytes,11,opt,name=query_key,json=queryKey,proto3" json:"query_key,omitempty"` // set is used outside of TotalQueryData QueryInfo *common.QueryInfo `protobuf:"bytes,12,opt,name=query_info,json=queryInfo,proto3" json:"query_info,omitempty"` // set is used outside of TotalQueryData @@ -1957,7 +1957,7 @@ func (x *SegmentMetrics) GetHostname() string { return "" } -func (x *SegmentMetrics) GetCollectTime() *timestamp.Timestamp { +func (x *SegmentMetrics) GetCollectTime() *timestamppb.Timestamp { if x != nil { return x.CollectTime } @@ -1978,14 +1978,14 @@ func (x *SegmentMetrics) GetQueryStatus() common.QueryStatus { return common.QueryStatus(0) } -func (x *SegmentMetrics) GetStartTime() *timestamp.Timestamp { +func (x *SegmentMetrics) GetStartTime() *timestamppb.Timestamp { if x != nil { return x.StartTime } return nil } -func (x *SegmentMetrics) GetEndTime() *timestamp.Timestamp { +func (x *SegmentMetrics) GetEndTime() *timestamppb.Timestamp { if x != nil { return x.EndTime } @@ -2671,7 +2671,7 @@ var file_api_proto_agent_master_yagpcc_get_service_proto_goTypes = []any{ (*common.SessionState)(nil), // 22: yagpcc.SessionState (*common.QueryKey)(nil), // 23: yagpcc.QueryKey (*common.SessionKey)(nil), // 24: yagpcc.SessionKey - (*timestamp.Timestamp)(nil), // 25: google.protobuf.Timestamp + (*timestamppb.Timestamp)(nil), // 25: google.protobuf.Timestamp (*common.QueryInfo)(nil), // 26: yagpcc.QueryInfo (common.QueryStatus)(0), // 27: yagpcc.QueryStatus (*common.GPMetrics)(nil), // 28: yagpcc.GPMetrics diff --git a/api/proto/agent_master/yagpcc_get_service_grpc.pb.go b/api/proto/agent_master/yagpcc_get_service_grpc.pb.go index 892c20d..896bd75 100644 --- a/api/proto/agent_master/yagpcc_get_service_grpc.pb.go +++ b/api/proto/agent_master/yagpcc_get_service_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.6.1 -// - protoc v3.12.4 +// - protoc v6.33.4 // source: api/proto/agent_master/yagpcc_get_service.proto package greenplum diff --git a/api/proto/agent_segment/yagpcc_control_service.pb.go b/api/proto/agent_segment/yagpcc_control_service.pb.go index e14871a..bd0d6fd 100644 --- a/api/proto/agent_segment/yagpcc_control_service.pb.go +++ b/api/proto/agent_segment/yagpcc_control_service.pb.go @@ -1,15 +1,15 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.36.11 -// protoc v3.12.4 +// protoc v6.33.4 // source: api/proto/agent_segment/yagpcc_control_service.proto package greenplum import ( - timestamp "github.com/golang/protobuf/ptypes/timestamp" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" unsafe "unsafe" @@ -146,7 +146,7 @@ func (*GetInfoReq) Descriptor() ([]byte, []int) { type InfoRepsonse struct { state protoimpl.MessageState `protogen:"open.v1"` Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` - ResetTime *timestamp.Timestamp `protobuf:"bytes,2,opt,name=reset_time,json=resetTime,proto3" json:"reset_time,omitempty"` + ResetTime *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=reset_time,json=resetTime,proto3" json:"reset_time,omitempty"` QueriesCount uint64 `protobuf:"varint,3,opt,name=queries_count,json=queriesCount,proto3" json:"queries_count,omitempty"` PlannodesCount uint64 `protobuf:"varint,4,opt,name=plannodes_count,json=plannodesCount,proto3" json:"plannodes_count,omitempty"` QueriesWipedOut uint64 `protobuf:"varint,5,opt,name=queries_wiped_out,json=queriesWipedOut,proto3" json:"queries_wiped_out,omitempty"` @@ -196,7 +196,7 @@ func (x *InfoRepsonse) GetVersion() string { return "" } -func (x *InfoRepsonse) GetResetTime() *timestamp.Timestamp { +func (x *InfoRepsonse) GetResetTime() *timestamppb.Timestamp { if x != nil { return x.ResetTime } @@ -368,7 +368,7 @@ var file_api_proto_agent_segment_yagpcc_control_service_proto_goTypes = []any{ (*GetInfoReq)(nil), // 2: yagpcc.GetInfoReq (*InfoRepsonse)(nil), // 3: yagpcc.InfoRepsonse (*ControlResponse)(nil), // 4: yagpcc.ControlResponse - (*timestamp.Timestamp)(nil), // 5: google.protobuf.Timestamp + (*timestamppb.Timestamp)(nil), // 5: google.protobuf.Timestamp } var file_api_proto_agent_segment_yagpcc_control_service_proto_depIdxs = []int32{ 5, // 0: yagpcc.InfoRepsonse.reset_time:type_name -> google.protobuf.Timestamp diff --git a/api/proto/agent_segment/yagpcc_control_service_grpc.pb.go b/api/proto/agent_segment/yagpcc_control_service_grpc.pb.go index b6cd8e0..52f4359 100644 --- a/api/proto/agent_segment/yagpcc_control_service_grpc.pb.go +++ b/api/proto/agent_segment/yagpcc_control_service_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.6.1 -// - protoc v3.12.4 +// - protoc v6.33.4 // source: api/proto/agent_segment/yagpcc_control_service.proto package greenplum diff --git a/api/proto/agent_segment/yagpcc_get_service.pb.go b/api/proto/agent_segment/yagpcc_get_service.pb.go index 0217854..ff52231 100644 --- a/api/proto/agent_segment/yagpcc_get_service.pb.go +++ b/api/proto/agent_segment/yagpcc_get_service.pb.go @@ -1,16 +1,16 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.36.11 -// protoc v3.12.4 +// protoc v6.33.4 // source: api/proto/agent_segment/yagpcc_get_service.proto package greenplum import ( - timestamp "github.com/golang/protobuf/ptypes/timestamp" common "github.com/open-gpdb/yagpcc/api/proto/common" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" unsafe "unsafe" @@ -26,8 +26,8 @@ const ( type QueryData struct { state protoimpl.MessageState `protogen:"open.v1"` QueryStatus common.QueryStatus `protobuf:"varint,1,opt,name=query_status,json=queryStatus,proto3,enum=yagpcc.QueryStatus" json:"query_status,omitempty"` - QueryStart *timestamp.Timestamp `protobuf:"bytes,2,opt,name=query_start,json=queryStart,proto3" json:"query_start,omitempty"` - QueryEnd *timestamp.Timestamp `protobuf:"bytes,3,opt,name=query_end,json=queryEnd,proto3" json:"query_end,omitempty"` + QueryStart *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=query_start,json=queryStart,proto3" json:"query_start,omitempty"` + QueryEnd *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=query_end,json=queryEnd,proto3" json:"query_end,omitempty"` QueryKey *common.QueryKey `protobuf:"bytes,4,opt,name=query_key,json=queryKey,proto3" json:"query_key,omitempty"` SegmentKey *common.SegmentKey `protobuf:"bytes,5,opt,name=segment_key,json=segmentKey,proto3" json:"segment_key,omitempty"` QueryInfo *common.QueryInfo `protobuf:"bytes,6,opt,name=query_info,json=queryInfo,proto3" json:"query_info,omitempty"` @@ -75,14 +75,14 @@ func (x *QueryData) GetQueryStatus() common.QueryStatus { return common.QueryStatus(0) } -func (x *QueryData) GetQueryStart() *timestamp.Timestamp { +func (x *QueryData) GetQueryStart() *timestamppb.Timestamp { if x != nil { return x.QueryStart } return nil } -func (x *QueryData) GetQueryEnd() *timestamp.Timestamp { +func (x *QueryData) GetQueryEnd() *timestamppb.Timestamp { if x != nil { return x.QueryEnd } @@ -178,8 +178,8 @@ func (x *GetQueriesInfoResponse) GetQueriesData() []*QueryData { type GetQueriesInfoReq struct { state protoimpl.MessageState `protogen:"open.v1"` FilterQueries []*common.QueryKey `protobuf:"bytes,1,rep,name=filter_queries,json=filterQueries,proto3" json:"filter_queries,omitempty"` // if set show queries with specific QueryKey's - FromTime *timestamp.Timestamp `protobuf:"bytes,2,opt,name=from_time,json=fromTime,proto3" json:"from_time,omitempty"` // if set filter out entries with query start before from_time - ToTime *timestamp.Timestamp `protobuf:"bytes,3,opt,name=to_time,json=toTime,proto3" json:"to_time,omitempty"` // if set filter out entries with query end after to_time + FromTime *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=from_time,json=fromTime,proto3" json:"from_time,omitempty"` // if set filter out entries with query start before from_time + ToTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=to_time,json=toTime,proto3" json:"to_time,omitempty"` // if set filter out entries with query end after to_time ClearSent bool `protobuf:"varint,4,opt,name=clear_sent,json=clearSent,proto3" json:"clear_sent,omitempty"` // clear info after sent query data unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -222,14 +222,14 @@ func (x *GetQueriesInfoReq) GetFilterQueries() []*common.QueryKey { return nil } -func (x *GetQueriesInfoReq) GetFromTime() *timestamp.Timestamp { +func (x *GetQueriesInfoReq) GetFromTime() *timestamppb.Timestamp { if x != nil { return x.FromTime } return nil } -func (x *GetQueriesInfoReq) GetToTime() *timestamp.Timestamp { +func (x *GetQueriesInfoReq) GetToTime() *timestamppb.Timestamp { if x != nil { return x.ToTime } @@ -451,7 +451,7 @@ var file_api_proto_agent_segment_yagpcc_get_service_proto_goTypes = []any{ (*SegmentProcess)(nil), // 4: yagpcc.SegmentProcess (*GetPidProcInfoReq)(nil), // 5: yagpcc.GetPidProcInfoReq (common.QueryStatus)(0), // 6: yagpcc.QueryStatus - (*timestamp.Timestamp)(nil), // 7: google.protobuf.Timestamp + (*timestamppb.Timestamp)(nil), // 7: google.protobuf.Timestamp (*common.QueryKey)(nil), // 8: yagpcc.QueryKey (*common.SegmentKey)(nil), // 9: yagpcc.SegmentKey (*common.QueryInfo)(nil), // 10: yagpcc.QueryInfo diff --git a/api/proto/agent_segment/yagpcc_get_service_grpc.pb.go b/api/proto/agent_segment/yagpcc_get_service_grpc.pb.go index d8659da..01b8a31 100644 --- a/api/proto/agent_segment/yagpcc_get_service_grpc.pb.go +++ b/api/proto/agent_segment/yagpcc_get_service_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.6.1 -// - protoc v3.12.4 +// - protoc v6.33.4 // source: api/proto/agent_segment/yagpcc_get_service.proto package greenplum diff --git a/api/proto/agent_segment/yagpcc_set_service.pb.go b/api/proto/agent_segment/yagpcc_set_service.pb.go index 1f075ac..6561df0 100644 --- a/api/proto/agent_segment/yagpcc_set_service.pb.go +++ b/api/proto/agent_segment/yagpcc_set_service.pb.go @@ -1,16 +1,16 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.36.11 -// protoc v3.12.4 +// protoc v6.33.4 // source: api/proto/agent_segment/yagpcc_set_service.proto package greenplum import ( - timestamp "github.com/golang/protobuf/ptypes/timestamp" common "github.com/open-gpdb/yagpcc/api/proto/common" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" unsafe "unsafe" @@ -127,14 +127,14 @@ func (x *MetricResponse) GetErrorText() string { type SetQueryReq struct { state protoimpl.MessageState `protogen:"open.v1"` QueryStatus common.QueryStatus `protobuf:"varint,1,opt,name=query_status,json=queryStatus,proto3,enum=yagpcc.QueryStatus" json:"query_status,omitempty"` - Datetime *timestamp.Timestamp `protobuf:"bytes,2,opt,name=datetime,proto3" json:"datetime,omitempty"` + Datetime *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=datetime,proto3" json:"datetime,omitempty"` QueryKey *common.QueryKey `protobuf:"bytes,3,opt,name=query_key,json=queryKey,proto3" json:"query_key,omitempty"` SegmentKey *common.SegmentKey `protobuf:"bytes,4,opt,name=segment_key,json=segmentKey,proto3" json:"segment_key,omitempty"` QueryInfo *common.QueryInfo `protobuf:"bytes,5,opt,name=query_info,json=queryInfo,proto3" json:"query_info,omitempty"` QueryMetrics *common.GPMetrics `protobuf:"bytes,6,opt,name=query_metrics,json=queryMetrics,proto3" json:"query_metrics,omitempty"` - SubmitTime *timestamp.Timestamp `protobuf:"bytes,8,opt,name=submit_time,json=submitTime,proto3" json:"submit_time,omitempty"` - StartTime *timestamp.Timestamp `protobuf:"bytes,9,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` - EndTime *timestamp.Timestamp `protobuf:"bytes,10,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"` + SubmitTime *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=submit_time,json=submitTime,proto3" json:"submit_time,omitempty"` + StartTime *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` + EndTime *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"` AddInfo *common.AdditionalQueryInfo `protobuf:"bytes,11,opt,name=add_info,json=addInfo,proto3" json:"add_info,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -177,7 +177,7 @@ func (x *SetQueryReq) GetQueryStatus() common.QueryStatus { return common.QueryStatus(0) } -func (x *SetQueryReq) GetDatetime() *timestamp.Timestamp { +func (x *SetQueryReq) GetDatetime() *timestamppb.Timestamp { if x != nil { return x.Datetime } @@ -212,21 +212,21 @@ func (x *SetQueryReq) GetQueryMetrics() *common.GPMetrics { return nil } -func (x *SetQueryReq) GetSubmitTime() *timestamp.Timestamp { +func (x *SetQueryReq) GetSubmitTime() *timestamppb.Timestamp { if x != nil { return x.SubmitTime } return nil } -func (x *SetQueryReq) GetStartTime() *timestamp.Timestamp { +func (x *SetQueryReq) GetStartTime() *timestamppb.Timestamp { if x != nil { return x.StartTime } return nil } -func (x *SetQueryReq) GetEndTime() *timestamp.Timestamp { +func (x *SetQueryReq) GetEndTime() *timestamppb.Timestamp { if x != nil { return x.EndTime } @@ -292,7 +292,7 @@ var file_api_proto_agent_segment_yagpcc_set_service_proto_goTypes = []any{ (*MetricResponse)(nil), // 1: yagpcc.MetricResponse (*SetQueryReq)(nil), // 2: yagpcc.SetQueryReq (common.QueryStatus)(0), // 3: yagpcc.QueryStatus - (*timestamp.Timestamp)(nil), // 4: google.protobuf.Timestamp + (*timestamppb.Timestamp)(nil), // 4: google.protobuf.Timestamp (*common.QueryKey)(nil), // 5: yagpcc.QueryKey (*common.SegmentKey)(nil), // 6: yagpcc.SegmentKey (*common.QueryInfo)(nil), // 7: yagpcc.QueryInfo diff --git a/api/proto/agent_segment/yagpcc_set_service_grpc.pb.go b/api/proto/agent_segment/yagpcc_set_service_grpc.pb.go index c762732..d1e4663 100644 --- a/api/proto/agent_segment/yagpcc_set_service_grpc.pb.go +++ b/api/proto/agent_segment/yagpcc_set_service_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.6.1 -// - protoc v3.12.4 +// - protoc v6.33.4 // source: api/proto/agent_segment/yagpcc_set_service.proto package greenplum diff --git a/api/proto/common/yagpcc_metrics.pb.go b/api/proto/common/yagpcc_metrics.pb.go index f344d5d..03af38c 100644 --- a/api/proto/common/yagpcc_metrics.pb.go +++ b/api/proto/common/yagpcc_metrics.pb.go @@ -1,15 +1,15 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.36.11 -// protoc v3.12.4 +// protoc v6.33.4 // source: api/proto/common/yagpcc_metrics.proto package greenplum import ( - timestamp "github.com/golang/protobuf/ptypes/timestamp" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" unsafe "unsafe" @@ -173,11 +173,11 @@ type QueryInfo struct { // analyze_text: explain analyze in text format. AnalyzeText string `protobuf:"bytes,11,opt,name=analyze_text,json=analyzeText,proto3" json:"analyze_text,omitempty"` // submit time: time when query was submitted - SubmitTime *timestamp.Timestamp `protobuf:"bytes,12,opt,name=submit_time,json=submitTime,proto3" json:"submit_time,omitempty"` + SubmitTime *timestamppb.Timestamp `protobuf:"bytes,12,opt,name=submit_time,json=submitTime,proto3" json:"submit_time,omitempty"` // start time: time when query started execution - StartTime *timestamp.Timestamp `protobuf:"bytes,13,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` + StartTime *timestamppb.Timestamp `protobuf:"bytes,13,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` // end time: time when query finished - EndTime *timestamp.Timestamp `protobuf:"bytes,14,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"` + EndTime *timestamppb.Timestamp `protobuf:"bytes,14,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -291,21 +291,21 @@ func (x *QueryInfo) GetAnalyzeText() string { return "" } -func (x *QueryInfo) GetSubmitTime() *timestamp.Timestamp { +func (x *QueryInfo) GetSubmitTime() *timestamppb.Timestamp { if x != nil { return x.SubmitTime } return nil } -func (x *QueryInfo) GetStartTime() *timestamp.Timestamp { +func (x *QueryInfo) GetStartTime() *timestamppb.Timestamp { if x != nil { return x.StartTime } return nil } -func (x *QueryInfo) GetEndTime() *timestamp.Timestamp { +func (x *QueryInfo) GetEndTime() *timestamppb.Timestamp { if x != nil { return x.EndTime } @@ -1604,25 +1604,25 @@ type ProcStat struct { // the process. Tpgid int32 `protobuf:"varint,8,opt,name=tpgid,proto3" json:"tpgid,omitempty"` // The kernel flags word of the process. - Flags uint32 `protobuf:"varint,9,opt,name=flags,proto3" json:"flags,omitempty"` + Flags int32 `protobuf:"varint,9,opt,name=flags,proto3" json:"flags,omitempty"` // The number of minor faults the process has made which have not required // loading a memory page from disk. - MinFlt uint32 `protobuf:"varint,10,opt,name=min_flt,json=minFlt,proto3" json:"min_flt,omitempty"` + MinFlt int32 `protobuf:"varint,10,opt,name=min_flt,json=minFlt,proto3" json:"min_flt,omitempty"` // The number of minor faults that the process's waited-for children have // made. - CminFlt uint32 `protobuf:"varint,11,opt,name=cmin_flt,json=cminFlt,proto3" json:"cmin_flt,omitempty"` + CminFlt int32 `protobuf:"varint,11,opt,name=cmin_flt,json=cminFlt,proto3" json:"cmin_flt,omitempty"` // The number of major faults the process has made which have required // loading a memory page from disk. - MajFlt uint32 `protobuf:"varint,12,opt,name=maj_flt,json=majFlt,proto3" json:"maj_flt,omitempty"` + MajFlt int32 `protobuf:"varint,12,opt,name=maj_flt,json=majFlt,proto3" json:"maj_flt,omitempty"` // The number of major faults that the process's waited-for children have // made. - CmajFlt uint32 `protobuf:"varint,13,opt,name=cmaj_flt,json=cmajFlt,proto3" json:"cmaj_flt,omitempty"` + CmajFlt int32 `protobuf:"varint,13,opt,name=cmaj_flt,json=cmajFlt,proto3" json:"cmaj_flt,omitempty"` // Amount of time that this process has been scheduled in user mode, // measured in clock ticks. - Utime uint32 `protobuf:"varint,14,opt,name=utime,proto3" json:"utime,omitempty"` + Utime int32 `protobuf:"varint,14,opt,name=utime,proto3" json:"utime,omitempty"` // Amount of time that this process has been scheduled in kernel mode, // measured in clock ticks. - Stime uint32 `protobuf:"varint,15,opt,name=stime,proto3" json:"stime,omitempty"` + Stime int32 `protobuf:"varint,15,opt,name=stime,proto3" json:"stime,omitempty"` // Amount of time that this process's waited-for children have been // scheduled in user mode, measured in clock ticks. Cutime int32 `protobuf:"varint,16,opt,name=cutime,proto3" json:"cutime,omitempty"` @@ -1639,28 +1639,28 @@ type ProcStat struct { NumThreads int32 `protobuf:"varint,20,opt,name=num_threads,json=numThreads,proto3" json:"num_threads,omitempty"` // The time the process started after system boot, the value is expressed // in clock ticks. - Starttime uint64 `protobuf:"varint,21,opt,name=starttime,proto3" json:"starttime,omitempty"` + Starttime int64 `protobuf:"varint,21,opt,name=starttime,proto3" json:"starttime,omitempty"` // Virtual memory size in bytes. - Vsize uint32 `protobuf:"varint,22,opt,name=vsize,proto3" json:"vsize,omitempty"` + Vsize int64 `protobuf:"varint,22,opt,name=vsize,proto3" json:"vsize,omitempty"` // Resident set size in pages. - Rss int32 `protobuf:"varint,23,opt,name=rss,proto3" json:"rss,omitempty"` + Rss int64 `protobuf:"varint,23,opt,name=rss,proto3" json:"rss,omitempty"` // Soft limit in bytes on the rss of the process. - RssLimit uint64 `protobuf:"varint,24,opt,name=rss_limit,json=rssLimit,proto3" json:"rss_limit,omitempty"` + RssLimit int64 `protobuf:"varint,24,opt,name=rss_limit,json=rssLimit,proto3" json:"rss_limit,omitempty"` // The address above which program text can run. - StartCode uint64 `protobuf:"varint,25,opt,name=start_code,json=startCode,proto3" json:"start_code,omitempty"` + StartCode int64 `protobuf:"varint,25,opt,name=start_code,json=startCode,proto3" json:"start_code,omitempty"` // The address below which program text can run. - EndCode uint64 `protobuf:"varint,26,opt,name=end_code,json=endCode,proto3" json:"end_code,omitempty"` + EndCode int64 `protobuf:"varint,26,opt,name=end_code,json=endCode,proto3" json:"end_code,omitempty"` // The address of the start (i.e., bottom) of the stack. - StartStack uint64 `protobuf:"varint,27,opt,name=start_stack,json=startStack,proto3" json:"start_stack,omitempty"` + StartStack int64 `protobuf:"varint,27,opt,name=start_stack,json=startStack,proto3" json:"start_stack,omitempty"` // CPU number last executed on. - Processor uint32 `protobuf:"varint,28,opt,name=processor,proto3" json:"processor,omitempty"` + Processor int32 `protobuf:"varint,28,opt,name=processor,proto3" json:"processor,omitempty"` // Real-time scheduling priority, a number in the range 1 to 99 for processes // scheduled under a real-time policy, or 0, for non-real-time processes. - RtPriority uint32 `protobuf:"varint,29,opt,name=rt_priority,json=rtPriority,proto3" json:"rt_priority,omitempty"` + RtPriority int32 `protobuf:"varint,29,opt,name=rt_priority,json=rtPriority,proto3" json:"rt_priority,omitempty"` // Scheduling policy. - Policy uint32 `protobuf:"varint,30,opt,name=policy,proto3" json:"policy,omitempty"` + Policy int32 `protobuf:"varint,30,opt,name=policy,proto3" json:"policy,omitempty"` // Aggregated block I/O delays, measured in clock ticks (centiseconds). - DelayAcctBlkIoTicks uint64 `protobuf:"varint,31,opt,name=delay_acct_blk_io_ticks,json=delayAcctBlkIoTicks,proto3" json:"delay_acct_blk_io_ticks,omitempty"` + DelayAcctBlkIoTicks int64 `protobuf:"varint,31,opt,name=delay_acct_blk_io_ticks,json=delayAcctBlkIoTicks,proto3" json:"delay_acct_blk_io_ticks,omitempty"` // Guest time of the process (time spent running a virtual CPU for a guest // operating system), measured in clock ticks. GuestTime int32 `protobuf:"varint,32,opt,name=guest_time,json=guestTime,proto3" json:"guest_time,omitempty"` @@ -1756,49 +1756,49 @@ func (x *ProcStat) GetTpgid() int32 { return 0 } -func (x *ProcStat) GetFlags() uint32 { +func (x *ProcStat) GetFlags() int32 { if x != nil { return x.Flags } return 0 } -func (x *ProcStat) GetMinFlt() uint32 { +func (x *ProcStat) GetMinFlt() int32 { if x != nil { return x.MinFlt } return 0 } -func (x *ProcStat) GetCminFlt() uint32 { +func (x *ProcStat) GetCminFlt() int32 { if x != nil { return x.CminFlt } return 0 } -func (x *ProcStat) GetMajFlt() uint32 { +func (x *ProcStat) GetMajFlt() int32 { if x != nil { return x.MajFlt } return 0 } -func (x *ProcStat) GetCmajFlt() uint32 { +func (x *ProcStat) GetCmajFlt() int32 { if x != nil { return x.CmajFlt } return 0 } -func (x *ProcStat) GetUtime() uint32 { +func (x *ProcStat) GetUtime() int32 { if x != nil { return x.Utime } return 0 } -func (x *ProcStat) GetStime() uint32 { +func (x *ProcStat) GetStime() int32 { if x != nil { return x.Stime } @@ -1840,77 +1840,77 @@ func (x *ProcStat) GetNumThreads() int32 { return 0 } -func (x *ProcStat) GetStarttime() uint64 { +func (x *ProcStat) GetStarttime() int64 { if x != nil { return x.Starttime } return 0 } -func (x *ProcStat) GetVsize() uint32 { +func (x *ProcStat) GetVsize() int64 { if x != nil { return x.Vsize } return 0 } -func (x *ProcStat) GetRss() int32 { +func (x *ProcStat) GetRss() int64 { if x != nil { return x.Rss } return 0 } -func (x *ProcStat) GetRssLimit() uint64 { +func (x *ProcStat) GetRssLimit() int64 { if x != nil { return x.RssLimit } return 0 } -func (x *ProcStat) GetStartCode() uint64 { +func (x *ProcStat) GetStartCode() int64 { if x != nil { return x.StartCode } return 0 } -func (x *ProcStat) GetEndCode() uint64 { +func (x *ProcStat) GetEndCode() int64 { if x != nil { return x.EndCode } return 0 } -func (x *ProcStat) GetStartStack() uint64 { +func (x *ProcStat) GetStartStack() int64 { if x != nil { return x.StartStack } return 0 } -func (x *ProcStat) GetProcessor() uint32 { +func (x *ProcStat) GetProcessor() int32 { if x != nil { return x.Processor } return 0 } -func (x *ProcStat) GetRtPriority() uint32 { +func (x *ProcStat) GetRtPriority() int32 { if x != nil { return x.RtPriority } return 0 } -func (x *ProcStat) GetPolicy() uint32 { +func (x *ProcStat) GetPolicy() int32 { if x != nil { return x.Policy } return 0 } -func (x *ProcStat) GetDelayAcctBlkIoTicks() uint64 { +func (x *ProcStat) GetDelayAcctBlkIoTicks() int64 { if x != nil { return x.DelayAcctBlkIoTicks } @@ -1943,61 +1943,61 @@ type ProcStatus struct { // Thread group ID. Tgid int32 `protobuf:"varint,3,opt,name=tgid,proto3" json:"tgid,omitempty"` // List of Pid namespace. - NsPids []uint64 `protobuf:"varint,4,rep,packed,name=ns_pids,json=nsPids,proto3" json:"ns_pids,omitempty"` + NsPids []int64 `protobuf:"varint,4,rep,packed,name=ns_pids,json=nsPids,proto3" json:"ns_pids,omitempty"` // Peak virtual memory size. - VmPeak uint64 `protobuf:"varint,5,opt,name=vm_peak,json=vmPeak,proto3" json:"vm_peak,omitempty"` + VmPeak int64 `protobuf:"varint,5,opt,name=vm_peak,json=vmPeak,proto3" json:"vm_peak,omitempty"` // Virtual memory size. - VmSize uint64 `protobuf:"varint,6,opt,name=vm_size,json=vmSize,proto3" json:"vm_size,omitempty"` + VmSize int64 `protobuf:"varint,6,opt,name=vm_size,json=vmSize,proto3" json:"vm_size,omitempty"` // Locked memory size. - VmLck uint64 `protobuf:"varint,7,opt,name=vm_lck,json=vmLck,proto3" json:"vm_lck,omitempty"` + VmLck int64 `protobuf:"varint,7,opt,name=vm_lck,json=vmLck,proto3" json:"vm_lck,omitempty"` // Pinned memory size. - VmPin uint64 `protobuf:"varint,8,opt,name=vm_pin,json=vmPin,proto3" json:"vm_pin,omitempty"` + VmPin int64 `protobuf:"varint,8,opt,name=vm_pin,json=vmPin,proto3" json:"vm_pin,omitempty"` // Peak resident set size. - VmHwm uint64 `protobuf:"varint,9,opt,name=vm_hwm,json=vmHwm,proto3" json:"vm_hwm,omitempty"` + VmHwm int64 `protobuf:"varint,9,opt,name=vm_hwm,json=vmHwm,proto3" json:"vm_hwm,omitempty"` // Resident set size (sum of RssAnon RssFile and RssShmem). - VmRss uint64 `protobuf:"varint,10,opt,name=vm_rss,json=vmRss,proto3" json:"vm_rss,omitempty"` + VmRss int64 `protobuf:"varint,10,opt,name=vm_rss,json=vmRss,proto3" json:"vm_rss,omitempty"` // Size of resident anonymous memory. - RssAnon uint64 `protobuf:"varint,11,opt,name=rss_anon,json=rssAnon,proto3" json:"rss_anon,omitempty"` + RssAnon int64 `protobuf:"varint,11,opt,name=rss_anon,json=rssAnon,proto3" json:"rss_anon,omitempty"` // Size of resident file mappings. - RssFile uint64 `protobuf:"varint,12,opt,name=rss_file,json=rssFile,proto3" json:"rss_file,omitempty"` + RssFile int64 `protobuf:"varint,12,opt,name=rss_file,json=rssFile,proto3" json:"rss_file,omitempty"` // Size of resident shared memory. - RssShmem uint64 `protobuf:"varint,13,opt,name=rss_shmem,json=rssShmem,proto3" json:"rss_shmem,omitempty"` + RssShmem int64 `protobuf:"varint,13,opt,name=rss_shmem,json=rssShmem,proto3" json:"rss_shmem,omitempty"` // Size of data segments. - VmData uint64 `protobuf:"varint,14,opt,name=vm_data,json=vmData,proto3" json:"vm_data,omitempty"` + VmData int64 `protobuf:"varint,14,opt,name=vm_data,json=vmData,proto3" json:"vm_data,omitempty"` // Size of stack segments. - VmStk uint64 `protobuf:"varint,15,opt,name=vm_stk,json=vmStk,proto3" json:"vm_stk,omitempty"` + VmStk int64 `protobuf:"varint,15,opt,name=vm_stk,json=vmStk,proto3" json:"vm_stk,omitempty"` // Size of text segments. - VmExe uint64 `protobuf:"varint,16,opt,name=vm_exe,json=vmExe,proto3" json:"vm_exe,omitempty"` + VmExe int64 `protobuf:"varint,16,opt,name=vm_exe,json=vmExe,proto3" json:"vm_exe,omitempty"` // Shared library code size. - VmLib uint64 `protobuf:"varint,17,opt,name=vm_lib,json=vmLib,proto3" json:"vm_lib,omitempty"` + VmLib int64 `protobuf:"varint,17,opt,name=vm_lib,json=vmLib,proto3" json:"vm_lib,omitempty"` // Page table entries size. - VmPte uint64 `protobuf:"varint,18,opt,name=vm_pte,json=vmPte,proto3" json:"vm_pte,omitempty"` + VmPte int64 `protobuf:"varint,18,opt,name=vm_pte,json=vmPte,proto3" json:"vm_pte,omitempty"` // Size of second-level page tables. - VmPmd uint64 `protobuf:"varint,19,opt,name=vm_pmd,json=vmPmd,proto3" json:"vm_pmd,omitempty"` + VmPmd int64 `protobuf:"varint,19,opt,name=vm_pmd,json=vmPmd,proto3" json:"vm_pmd,omitempty"` // Swapped-out virtual memory size by anonymous private. - VmSwap uint64 `protobuf:"varint,20,opt,name=vm_swap,json=vmSwap,proto3" json:"vm_swap,omitempty"` + VmSwap int64 `protobuf:"varint,20,opt,name=vm_swap,json=vmSwap,proto3" json:"vm_swap,omitempty"` // Size of hugetlb memory portions. - HugetlbPages uint64 `protobuf:"varint,21,opt,name=hugetlb_pages,json=hugetlbPages,proto3" json:"hugetlb_pages,omitempty"` + HugetlbPages int64 `protobuf:"varint,21,opt,name=hugetlb_pages,json=hugetlbPages,proto3" json:"hugetlb_pages,omitempty"` // Number of voluntary context switches. - VoluntaryCtxtSwitches uint64 `protobuf:"varint,22,opt,name=voluntary_ctxt_switches,json=voluntaryCtxtSwitches,proto3" json:"voluntary_ctxt_switches,omitempty"` + VoluntaryCtxtSwitches int64 `protobuf:"varint,22,opt,name=voluntary_ctxt_switches,json=voluntaryCtxtSwitches,proto3" json:"voluntary_ctxt_switches,omitempty"` // Number of involuntary context switches. - NonVoluntaryCtxtSwitches uint64 `protobuf:"varint,23,opt,name=non_voluntary_ctxt_switches,json=nonVoluntaryCtxtSwitches,proto3" json:"non_voluntary_ctxt_switches,omitempty"` + NonVoluntaryCtxtSwitches int64 `protobuf:"varint,23,opt,name=non_voluntary_ctxt_switches,json=nonVoluntaryCtxtSwitches,proto3" json:"non_voluntary_ctxt_switches,omitempty"` // UIDs of the process (Real, effective, saved set, and filesystem UIDs). - Uids []uint64 `protobuf:"varint,24,rep,packed,name=uids,proto3" json:"uids,omitempty"` + Uids []int64 `protobuf:"varint,24,rep,packed,name=uids,proto3" json:"uids,omitempty"` // GIDs of the process (Real, effective, saved set, and filesystem GIDs). - Gids []uint64 `protobuf:"varint,25,rep,packed,name=gids,proto3" json:"gids,omitempty"` + Gids []int64 `protobuf:"varint,25,rep,packed,name=gids,proto3" json:"gids,omitempty"` // CpusAllowedList: List of cpu cores processes are allowed to run on. - CpusAllowedList []uint64 `protobuf:"varint,26,rep,packed,name=cpus_allowed_list,json=cpusAllowedList,proto3" json:"cpus_allowed_list,omitempty"` + CpusAllowedList []int64 `protobuf:"varint,26,rep,packed,name=cpus_allowed_list,json=cpusAllowedList,proto3" json:"cpus_allowed_list,omitempty"` // CapInh is the bitmap of inheritable capabilities. - CapInh uint64 `protobuf:"varint,27,opt,name=cap_inh,json=capInh,proto3" json:"cap_inh,omitempty"` + CapInh int64 `protobuf:"varint,27,opt,name=cap_inh,json=capInh,proto3" json:"cap_inh,omitempty"` // CapPrm is the bitmap of permitted capabilities. - CapPrm uint64 `protobuf:"varint,28,opt,name=cap_prm,json=capPrm,proto3" json:"cap_prm,omitempty"` + CapPrm int64 `protobuf:"varint,28,opt,name=cap_prm,json=capPrm,proto3" json:"cap_prm,omitempty"` // CapEff is the bitmap of effective capabilities. - CapEff uint64 `protobuf:"varint,29,opt,name=cap_eff,json=capEff,proto3" json:"cap_eff,omitempty"` + CapEff int64 `protobuf:"varint,29,opt,name=cap_eff,json=capEff,proto3" json:"cap_eff,omitempty"` // CapBnd is the bitmap of bounding capabilities. - CapBnd uint64 `protobuf:"varint,30,opt,name=cap_bnd,json=capBnd,proto3" json:"cap_bnd,omitempty"` + CapBnd int64 `protobuf:"varint,30,opt,name=cap_bnd,json=capBnd,proto3" json:"cap_bnd,omitempty"` // CapAmb is the bitmap of ambient capabilities. - CapAmb uint64 `protobuf:"varint,31,opt,name=cap_amb,json=capAmb,proto3" json:"cap_amb,omitempty"` + CapAmb int64 `protobuf:"varint,31,opt,name=cap_amb,json=capAmb,proto3" json:"cap_amb,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -2053,202 +2053,313 @@ func (x *ProcStatus) GetTgid() int32 { return 0 } -func (x *ProcStatus) GetNsPids() []uint64 { +func (x *ProcStatus) GetNsPids() []int64 { if x != nil { return x.NsPids } return nil } -func (x *ProcStatus) GetVmPeak() uint64 { +func (x *ProcStatus) GetVmPeak() int64 { if x != nil { return x.VmPeak } return 0 } -func (x *ProcStatus) GetVmSize() uint64 { +func (x *ProcStatus) GetVmSize() int64 { if x != nil { return x.VmSize } return 0 } -func (x *ProcStatus) GetVmLck() uint64 { +func (x *ProcStatus) GetVmLck() int64 { if x != nil { return x.VmLck } return 0 } -func (x *ProcStatus) GetVmPin() uint64 { +func (x *ProcStatus) GetVmPin() int64 { if x != nil { return x.VmPin } return 0 } -func (x *ProcStatus) GetVmHwm() uint64 { +func (x *ProcStatus) GetVmHwm() int64 { if x != nil { return x.VmHwm } return 0 } -func (x *ProcStatus) GetVmRss() uint64 { +func (x *ProcStatus) GetVmRss() int64 { if x != nil { return x.VmRss } return 0 } -func (x *ProcStatus) GetRssAnon() uint64 { +func (x *ProcStatus) GetRssAnon() int64 { if x != nil { return x.RssAnon } return 0 } -func (x *ProcStatus) GetRssFile() uint64 { +func (x *ProcStatus) GetRssFile() int64 { if x != nil { return x.RssFile } return 0 } -func (x *ProcStatus) GetRssShmem() uint64 { +func (x *ProcStatus) GetRssShmem() int64 { if x != nil { return x.RssShmem } return 0 } -func (x *ProcStatus) GetVmData() uint64 { +func (x *ProcStatus) GetVmData() int64 { if x != nil { return x.VmData } return 0 } -func (x *ProcStatus) GetVmStk() uint64 { +func (x *ProcStatus) GetVmStk() int64 { if x != nil { return x.VmStk } return 0 } -func (x *ProcStatus) GetVmExe() uint64 { +func (x *ProcStatus) GetVmExe() int64 { if x != nil { return x.VmExe } return 0 } -func (x *ProcStatus) GetVmLib() uint64 { +func (x *ProcStatus) GetVmLib() int64 { if x != nil { return x.VmLib } return 0 } -func (x *ProcStatus) GetVmPte() uint64 { +func (x *ProcStatus) GetVmPte() int64 { if x != nil { return x.VmPte } return 0 } -func (x *ProcStatus) GetVmPmd() uint64 { +func (x *ProcStatus) GetVmPmd() int64 { if x != nil { return x.VmPmd } return 0 } -func (x *ProcStatus) GetVmSwap() uint64 { +func (x *ProcStatus) GetVmSwap() int64 { if x != nil { return x.VmSwap } return 0 } -func (x *ProcStatus) GetHugetlbPages() uint64 { +func (x *ProcStatus) GetHugetlbPages() int64 { if x != nil { return x.HugetlbPages } return 0 } -func (x *ProcStatus) GetVoluntaryCtxtSwitches() uint64 { +func (x *ProcStatus) GetVoluntaryCtxtSwitches() int64 { if x != nil { return x.VoluntaryCtxtSwitches } return 0 } -func (x *ProcStatus) GetNonVoluntaryCtxtSwitches() uint64 { +func (x *ProcStatus) GetNonVoluntaryCtxtSwitches() int64 { if x != nil { return x.NonVoluntaryCtxtSwitches } return 0 } -func (x *ProcStatus) GetUids() []uint64 { +func (x *ProcStatus) GetUids() []int64 { if x != nil { return x.Uids } return nil } -func (x *ProcStatus) GetGids() []uint64 { +func (x *ProcStatus) GetGids() []int64 { if x != nil { return x.Gids } return nil } -func (x *ProcStatus) GetCpusAllowedList() []uint64 { +func (x *ProcStatus) GetCpusAllowedList() []int64 { if x != nil { return x.CpusAllowedList } return nil } -func (x *ProcStatus) GetCapInh() uint64 { +func (x *ProcStatus) GetCapInh() int64 { if x != nil { return x.CapInh } return 0 } -func (x *ProcStatus) GetCapPrm() uint64 { +func (x *ProcStatus) GetCapPrm() int64 { if x != nil { return x.CapPrm } return 0 } -func (x *ProcStatus) GetCapEff() uint64 { +func (x *ProcStatus) GetCapEff() int64 { if x != nil { return x.CapEff } return 0 } -func (x *ProcStatus) GetCapBnd() uint64 { +func (x *ProcStatus) GetCapBnd() int64 { if x != nil { return x.CapBnd } return 0 } -func (x *ProcStatus) GetCapAmb() uint64 { +func (x *ProcStatus) GetCapAmb() int64 { if x != nil { return x.CapAmb } return 0 } +// ProcIO models /proc//io counters: cumulative byte and syscall counts +// for the lifetime of the process. Master computes per-tick deltas from +// these values; spec at: +// +// https://www.kernel.org/doc/Documentation/filesystems/proc.rst +// +// (and https://pkg.go.dev/github.com/prometheus/procfs#ProcIO). +type ProcIO struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Bytes read by the process via read-like syscalls (returned to + // userspace), including bytes served from the page cache. Counter. + Rchar int64 `protobuf:"varint,1,opt,name=rchar,proto3" json:"rchar,omitempty"` + // Bytes written by the process via write-like syscalls (accepted from + // userspace), regardless of whether they have been flushed. Counter. + Wchar int64 `protobuf:"varint,2,opt,name=wchar,proto3" json:"wchar,omitempty"` + // Number of read-like syscalls invoked by the process. Counter. + Syscr int64 `protobuf:"varint,3,opt,name=syscr,proto3" json:"syscr,omitempty"` + // Number of write-like syscalls invoked by the process. Counter. + Syscw int64 `protobuf:"varint,4,opt,name=syscw,proto3" json:"syscw,omitempty"` + // Bytes the storage layer actually fetched on behalf of the process + // (i.e. reads that missed the page cache). Counter. + ReadBytes int64 `protobuf:"varint,5,opt,name=read_bytes,json=readBytes,proto3" json:"read_bytes,omitempty"` + // Bytes the storage layer was asked to write on behalf of the process. + // Counter. + WriteBytes int64 `protobuf:"varint,6,opt,name=write_bytes,json=writeBytes,proto3" json:"write_bytes,omitempty"` + // Bytes that were accounted as written but were never persisted (e.g. + // truncated before flush). Counter. + CancelledWriteBytes int64 `protobuf:"varint,7,opt,name=cancelled_write_bytes,json=cancelledWriteBytes,proto3" json:"cancelled_write_bytes,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProcIO) Reset() { + *x = ProcIO{} + mi := &file_api_proto_common_yagpcc_metrics_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProcIO) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProcIO) ProtoMessage() {} + +func (x *ProcIO) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_common_yagpcc_metrics_proto_msgTypes[13] + 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 ProcIO.ProtoReflect.Descriptor instead. +func (*ProcIO) Descriptor() ([]byte, []int) { + return file_api_proto_common_yagpcc_metrics_proto_rawDescGZIP(), []int{13} +} + +func (x *ProcIO) GetRchar() int64 { + if x != nil { + return x.Rchar + } + return 0 +} + +func (x *ProcIO) GetWchar() int64 { + if x != nil { + return x.Wchar + } + return 0 +} + +func (x *ProcIO) GetSyscr() int64 { + if x != nil { + return x.Syscr + } + return 0 +} + +func (x *ProcIO) GetSyscw() int64 { + if x != nil { + return x.Syscw + } + return 0 +} + +func (x *ProcIO) GetReadBytes() int64 { + if x != nil { + return x.ReadBytes + } + return 0 +} + +func (x *ProcIO) GetWriteBytes() int64 { + if x != nil { + return x.WriteBytes + } + return 0 +} + +func (x *ProcIO) GetCancelledWriteBytes() int64 { + if x != nil { + return x.CancelledWriteBytes + } + return 0 +} + type GpPidProcInfo struct { state protoimpl.MessageState `protogen:"open.v1"` // primary key for process info @@ -2257,15 +2368,17 @@ type GpPidProcInfo struct { Pid int64 `protobuf:"varint,3,opt,name=pid,proto3" json:"pid,omitempty"` // actual data Cmdline string `protobuf:"bytes,4,opt,name=cmdline,proto3" json:"cmdline,omitempty"` - ProcStat *ProcStat `protobuf:"bytes,5,opt,name=proc_stat,json=procStat,proto3" json:"proc_stat,omitempty"` - ProcStatus *ProcStatus `protobuf:"bytes,6,opt,name=proc_status,json=procStatus,proto3" json:"proc_status,omitempty"` + State string `protobuf:"bytes,5,opt,name=state,proto3" json:"state,omitempty"` + ProcStat *ProcStat `protobuf:"bytes,6,opt,name=proc_stat,json=procStat,proto3" json:"proc_stat,omitempty"` + ProcStatus *ProcStatus `protobuf:"bytes,7,opt,name=proc_status,json=procStatus,proto3" json:"proc_status,omitempty"` + ProcIo *ProcIO `protobuf:"bytes,8,opt,name=proc_io,json=procIo,proto3" json:"proc_io,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *GpPidProcInfo) Reset() { *x = GpPidProcInfo{} - mi := &file_api_proto_common_yagpcc_metrics_proto_msgTypes[13] + mi := &file_api_proto_common_yagpcc_metrics_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2277,7 +2390,7 @@ func (x *GpPidProcInfo) String() string { func (*GpPidProcInfo) ProtoMessage() {} func (x *GpPidProcInfo) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_common_yagpcc_metrics_proto_msgTypes[13] + mi := &file_api_proto_common_yagpcc_metrics_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2290,7 +2403,7 @@ func (x *GpPidProcInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use GpPidProcInfo.ProtoReflect.Descriptor instead. func (*GpPidProcInfo) Descriptor() ([]byte, []int) { - return file_api_proto_common_yagpcc_metrics_proto_rawDescGZIP(), []int{13} + return file_api_proto_common_yagpcc_metrics_proto_rawDescGZIP(), []int{14} } func (x *GpPidProcInfo) GetGpSegmentId() int64 { @@ -2321,6 +2434,13 @@ func (x *GpPidProcInfo) GetCmdline() string { return "" } +func (x *GpPidProcInfo) GetState() string { + if x != nil { + return x.State + } + return "" +} + func (x *GpPidProcInfo) GetProcStat() *ProcStat { if x != nil { return x.ProcStat @@ -2335,6 +2455,13 @@ func (x *GpPidProcInfo) GetProcStatus() *ProcStatus { return nil } +func (x *GpPidProcInfo) GetProcIo() *ProcIO { + if x != nil { + return x.ProcIo + } + return nil +} + type AggregatedMetrics struct { state protoimpl.MessageState `protogen:"open.v1"` Calls int64 `protobuf:"varint,1,opt,name=calls,proto3" json:"calls,omitempty"` @@ -2349,7 +2476,7 @@ type AggregatedMetrics struct { func (x *AggregatedMetrics) Reset() { *x = AggregatedMetrics{} - mi := &file_api_proto_common_yagpcc_metrics_proto_msgTypes[14] + mi := &file_api_proto_common_yagpcc_metrics_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2361,7 +2488,7 @@ func (x *AggregatedMetrics) String() string { func (*AggregatedMetrics) ProtoMessage() {} func (x *AggregatedMetrics) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_common_yagpcc_metrics_proto_msgTypes[14] + mi := &file_api_proto_common_yagpcc_metrics_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2374,7 +2501,7 @@ func (x *AggregatedMetrics) ProtoReflect() protoreflect.Message { // Deprecated: Use AggregatedMetrics.ProtoReflect.Descriptor instead. func (*AggregatedMetrics) Descriptor() ([]byte, []int) { - return file_api_proto_common_yagpcc_metrics_proto_rawDescGZIP(), []int{14} + return file_api_proto_common_yagpcc_metrics_proto_rawDescGZIP(), []int{15} } func (x *AggregatedMetrics) GetCalls() int64 { @@ -2554,34 +2681,34 @@ const file_api_proto_common_yagpcc_metrics_proto_rawDesc = "" + "\asession\x18\x06 \x01(\x05R\asession\x12\x10\n" + "\x03tty\x18\a \x01(\x05R\x03tty\x12\x14\n" + "\x05tpgid\x18\b \x01(\x05R\x05tpgid\x12\x14\n" + - "\x05flags\x18\t \x01(\rR\x05flags\x12\x17\n" + + "\x05flags\x18\t \x01(\x05R\x05flags\x12\x17\n" + "\amin_flt\x18\n" + - " \x01(\rR\x06minFlt\x12\x19\n" + - "\bcmin_flt\x18\v \x01(\rR\acminFlt\x12\x17\n" + - "\amaj_flt\x18\f \x01(\rR\x06majFlt\x12\x19\n" + - "\bcmaj_flt\x18\r \x01(\rR\acmajFlt\x12\x14\n" + - "\x05utime\x18\x0e \x01(\rR\x05utime\x12\x14\n" + - "\x05stime\x18\x0f \x01(\rR\x05stime\x12\x16\n" + + " \x01(\x05R\x06minFlt\x12\x19\n" + + "\bcmin_flt\x18\v \x01(\x05R\acminFlt\x12\x17\n" + + "\amaj_flt\x18\f \x01(\x05R\x06majFlt\x12\x19\n" + + "\bcmaj_flt\x18\r \x01(\x05R\acmajFlt\x12\x14\n" + + "\x05utime\x18\x0e \x01(\x05R\x05utime\x12\x14\n" + + "\x05stime\x18\x0f \x01(\x05R\x05stime\x12\x16\n" + "\x06cutime\x18\x10 \x01(\x05R\x06cutime\x12\x16\n" + "\x06cstime\x18\x11 \x01(\x05R\x06cstime\x12\x1a\n" + "\bpriority\x18\x12 \x01(\x05R\bpriority\x12\x12\n" + "\x04nice\x18\x13 \x01(\x05R\x04nice\x12\x1f\n" + "\vnum_threads\x18\x14 \x01(\x05R\n" + "numThreads\x12\x1c\n" + - "\tstarttime\x18\x15 \x01(\x04R\tstarttime\x12\x14\n" + - "\x05vsize\x18\x16 \x01(\rR\x05vsize\x12\x10\n" + - "\x03rss\x18\x17 \x01(\x05R\x03rss\x12\x1b\n" + - "\trss_limit\x18\x18 \x01(\x04R\brssLimit\x12\x1d\n" + + "\tstarttime\x18\x15 \x01(\x03R\tstarttime\x12\x14\n" + + "\x05vsize\x18\x16 \x01(\x03R\x05vsize\x12\x10\n" + + "\x03rss\x18\x17 \x01(\x03R\x03rss\x12\x1b\n" + + "\trss_limit\x18\x18 \x01(\x03R\brssLimit\x12\x1d\n" + "\n" + - "start_code\x18\x19 \x01(\x04R\tstartCode\x12\x19\n" + - "\bend_code\x18\x1a \x01(\x04R\aendCode\x12\x1f\n" + - "\vstart_stack\x18\x1b \x01(\x04R\n" + + "start_code\x18\x19 \x01(\x03R\tstartCode\x12\x19\n" + + "\bend_code\x18\x1a \x01(\x03R\aendCode\x12\x1f\n" + + "\vstart_stack\x18\x1b \x01(\x03R\n" + "startStack\x12\x1c\n" + - "\tprocessor\x18\x1c \x01(\rR\tprocessor\x12\x1f\n" + - "\vrt_priority\x18\x1d \x01(\rR\n" + + "\tprocessor\x18\x1c \x01(\x05R\tprocessor\x12\x1f\n" + + "\vrt_priority\x18\x1d \x01(\x05R\n" + "rtPriority\x12\x16\n" + - "\x06policy\x18\x1e \x01(\rR\x06policy\x124\n" + - "\x17delay_acct_blk_io_ticks\x18\x1f \x01(\x04R\x13delayAcctBlkIoTicks\x12\x1d\n" + + "\x06policy\x18\x1e \x01(\x05R\x06policy\x124\n" + + "\x17delay_acct_blk_io_ticks\x18\x1f \x01(\x03R\x13delayAcctBlkIoTicks\x12\x1d\n" + "\n" + "guest_time\x18 \x01(\x05R\tguestTime\x12\x1f\n" + "\vcguest_time\x18! \x01(\x05R\n" + @@ -2591,43 +2718,55 @@ const file_api_proto_common_yagpcc_metrics_proto_rawDesc = "" + "\x03pid\x18\x01 \x01(\x05R\x03pid\x12\x12\n" + "\x04name\x18\x02 \x01(\tR\x04name\x12\x12\n" + "\x04tgid\x18\x03 \x01(\x05R\x04tgid\x12\x17\n" + - "\ans_pids\x18\x04 \x03(\x04R\x06nsPids\x12\x17\n" + - "\avm_peak\x18\x05 \x01(\x04R\x06vmPeak\x12\x17\n" + - "\avm_size\x18\x06 \x01(\x04R\x06vmSize\x12\x15\n" + - "\x06vm_lck\x18\a \x01(\x04R\x05vmLck\x12\x15\n" + - "\x06vm_pin\x18\b \x01(\x04R\x05vmPin\x12\x15\n" + - "\x06vm_hwm\x18\t \x01(\x04R\x05vmHwm\x12\x15\n" + + "\ans_pids\x18\x04 \x03(\x03R\x06nsPids\x12\x17\n" + + "\avm_peak\x18\x05 \x01(\x03R\x06vmPeak\x12\x17\n" + + "\avm_size\x18\x06 \x01(\x03R\x06vmSize\x12\x15\n" + + "\x06vm_lck\x18\a \x01(\x03R\x05vmLck\x12\x15\n" + + "\x06vm_pin\x18\b \x01(\x03R\x05vmPin\x12\x15\n" + + "\x06vm_hwm\x18\t \x01(\x03R\x05vmHwm\x12\x15\n" + "\x06vm_rss\x18\n" + - " \x01(\x04R\x05vmRss\x12\x19\n" + - "\brss_anon\x18\v \x01(\x04R\arssAnon\x12\x19\n" + - "\brss_file\x18\f \x01(\x04R\arssFile\x12\x1b\n" + - "\trss_shmem\x18\r \x01(\x04R\brssShmem\x12\x17\n" + - "\avm_data\x18\x0e \x01(\x04R\x06vmData\x12\x15\n" + - "\x06vm_stk\x18\x0f \x01(\x04R\x05vmStk\x12\x15\n" + - "\x06vm_exe\x18\x10 \x01(\x04R\x05vmExe\x12\x15\n" + - "\x06vm_lib\x18\x11 \x01(\x04R\x05vmLib\x12\x15\n" + - "\x06vm_pte\x18\x12 \x01(\x04R\x05vmPte\x12\x15\n" + - "\x06vm_pmd\x18\x13 \x01(\x04R\x05vmPmd\x12\x17\n" + - "\avm_swap\x18\x14 \x01(\x04R\x06vmSwap\x12#\n" + - "\rhugetlb_pages\x18\x15 \x01(\x04R\fhugetlbPages\x126\n" + - "\x17voluntary_ctxt_switches\x18\x16 \x01(\x04R\x15voluntaryCtxtSwitches\x12=\n" + - "\x1bnon_voluntary_ctxt_switches\x18\x17 \x01(\x04R\x18nonVoluntaryCtxtSwitches\x12\x12\n" + - "\x04uids\x18\x18 \x03(\x04R\x04uids\x12\x12\n" + - "\x04gids\x18\x19 \x03(\x04R\x04gids\x12*\n" + - "\x11cpus_allowed_list\x18\x1a \x03(\x04R\x0fcpusAllowedList\x12\x17\n" + - "\acap_inh\x18\x1b \x01(\x04R\x06capInh\x12\x17\n" + - "\acap_prm\x18\x1c \x01(\x04R\x06capPrm\x12\x17\n" + - "\acap_eff\x18\x1d \x01(\x04R\x06capEff\x12\x17\n" + - "\acap_bnd\x18\x1e \x01(\x04R\x06capBnd\x12\x17\n" + - "\acap_amb\x18\x1f \x01(\x04R\x06capAmb\"\xdc\x01\n" + + " \x01(\x03R\x05vmRss\x12\x19\n" + + "\brss_anon\x18\v \x01(\x03R\arssAnon\x12\x19\n" + + "\brss_file\x18\f \x01(\x03R\arssFile\x12\x1b\n" + + "\trss_shmem\x18\r \x01(\x03R\brssShmem\x12\x17\n" + + "\avm_data\x18\x0e \x01(\x03R\x06vmData\x12\x15\n" + + "\x06vm_stk\x18\x0f \x01(\x03R\x05vmStk\x12\x15\n" + + "\x06vm_exe\x18\x10 \x01(\x03R\x05vmExe\x12\x15\n" + + "\x06vm_lib\x18\x11 \x01(\x03R\x05vmLib\x12\x15\n" + + "\x06vm_pte\x18\x12 \x01(\x03R\x05vmPte\x12\x15\n" + + "\x06vm_pmd\x18\x13 \x01(\x03R\x05vmPmd\x12\x17\n" + + "\avm_swap\x18\x14 \x01(\x03R\x06vmSwap\x12#\n" + + "\rhugetlb_pages\x18\x15 \x01(\x03R\fhugetlbPages\x126\n" + + "\x17voluntary_ctxt_switches\x18\x16 \x01(\x03R\x15voluntaryCtxtSwitches\x12=\n" + + "\x1bnon_voluntary_ctxt_switches\x18\x17 \x01(\x03R\x18nonVoluntaryCtxtSwitches\x12\x12\n" + + "\x04uids\x18\x18 \x03(\x03R\x04uids\x12\x12\n" + + "\x04gids\x18\x19 \x03(\x03R\x04gids\x12*\n" + + "\x11cpus_allowed_list\x18\x1a \x03(\x03R\x0fcpusAllowedList\x12\x17\n" + + "\acap_inh\x18\x1b \x01(\x03R\x06capInh\x12\x17\n" + + "\acap_prm\x18\x1c \x01(\x03R\x06capPrm\x12\x17\n" + + "\acap_eff\x18\x1d \x01(\x03R\x06capEff\x12\x17\n" + + "\acap_bnd\x18\x1e \x01(\x03R\x06capBnd\x12\x17\n" + + "\acap_amb\x18\x1f \x01(\x03R\x06capAmb\"\xd4\x01\n" + + "\x06ProcIO\x12\x14\n" + + "\x05rchar\x18\x01 \x01(\x03R\x05rchar\x12\x14\n" + + "\x05wchar\x18\x02 \x01(\x03R\x05wchar\x12\x14\n" + + "\x05syscr\x18\x03 \x01(\x03R\x05syscr\x12\x14\n" + + "\x05syscw\x18\x04 \x01(\x03R\x05syscw\x12\x1d\n" + + "\n" + + "read_bytes\x18\x05 \x01(\x03R\treadBytes\x12\x1f\n" + + "\vwrite_bytes\x18\x06 \x01(\x03R\n" + + "writeBytes\x122\n" + + "\x15cancelled_write_bytes\x18\a \x01(\x03R\x13cancelledWriteBytes\"\x9b\x02\n" + "\rGpPidProcInfo\x12\"\n" + "\rgp_segment_id\x18\x01 \x01(\x03R\vgpSegmentId\x12\x17\n" + "\asess_id\x18\x02 \x01(\x03R\x06sessId\x12\x10\n" + "\x03pid\x18\x03 \x01(\x03R\x03pid\x12\x18\n" + - "\acmdline\x18\x04 \x01(\tR\acmdline\x12-\n" + - "\tproc_stat\x18\x05 \x01(\v2\x10.yagpcc.ProcStatR\bprocStat\x123\n" + - "\vproc_status\x18\x06 \x01(\v2\x12.yagpcc.ProcStatusR\n" + - "procStatus\"\xbc\x01\n" + + "\acmdline\x18\x04 \x01(\tR\acmdline\x12\x14\n" + + "\x05state\x18\x05 \x01(\tR\x05state\x12-\n" + + "\tproc_stat\x18\x06 \x01(\v2\x10.yagpcc.ProcStatR\bprocStat\x123\n" + + "\vproc_status\x18\a \x01(\v2\x12.yagpcc.ProcStatusR\n" + + "procStatus\x12'\n" + + "\aproc_io\x18\b \x01(\v2\x0e.yagpcc.ProcIOR\x06procIo\"\xbc\x01\n" + "\x11AggregatedMetrics\x12\x14\n" + "\x05calls\x18\x01 \x01(\x03R\x05calls\x12\x19\n" + "\bmin_time\x18\x02 \x01(\x01R\aminTime\x12\x19\n" + @@ -2665,7 +2804,7 @@ func file_api_proto_common_yagpcc_metrics_proto_rawDescGZIP() []byte { } var file_api_proto_common_yagpcc_metrics_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_api_proto_common_yagpcc_metrics_proto_msgTypes = make([]protoimpl.MessageInfo, 15) +var file_api_proto_common_yagpcc_metrics_proto_msgTypes = make([]protoimpl.MessageInfo, 16) var file_api_proto_common_yagpcc_metrics_proto_goTypes = []any{ (QueryStatus)(0), // 0: yagpcc.QueryStatus (PlanGenerator)(0), // 1: yagpcc.PlanGenerator @@ -2682,15 +2821,16 @@ var file_api_proto_common_yagpcc_metrics_proto_goTypes = []any{ (*SpillInfo)(nil), // 12: yagpcc.SpillInfo (*ProcStat)(nil), // 13: yagpcc.ProcStat (*ProcStatus)(nil), // 14: yagpcc.ProcStatus - (*GpPidProcInfo)(nil), // 15: yagpcc.GpPidProcInfo - (*AggregatedMetrics)(nil), // 16: yagpcc.AggregatedMetrics - (*timestamp.Timestamp)(nil), // 17: google.protobuf.Timestamp + (*ProcIO)(nil), // 15: yagpcc.ProcIO + (*GpPidProcInfo)(nil), // 16: yagpcc.GpPidProcInfo + (*AggregatedMetrics)(nil), // 17: yagpcc.AggregatedMetrics + (*timestamppb.Timestamp)(nil), // 18: google.protobuf.Timestamp } var file_api_proto_common_yagpcc_metrics_proto_depIdxs = []int32{ 1, // 0: yagpcc.QueryInfo.generator:type_name -> yagpcc.PlanGenerator - 17, // 1: yagpcc.QueryInfo.submit_time:type_name -> google.protobuf.Timestamp - 17, // 2: yagpcc.QueryInfo.start_time:type_name -> google.protobuf.Timestamp - 17, // 3: yagpcc.QueryInfo.end_time:type_name -> google.protobuf.Timestamp + 18, // 1: yagpcc.QueryInfo.submit_time:type_name -> google.protobuf.Timestamp + 18, // 2: yagpcc.QueryInfo.start_time:type_name -> google.protobuf.Timestamp + 18, // 3: yagpcc.QueryInfo.end_time:type_name -> google.protobuf.Timestamp 8, // 4: yagpcc.GPMetrics.systemStat:type_name -> yagpcc.SystemStat 11, // 5: yagpcc.GPMetrics.instrumentation:type_name -> yagpcc.MetricInstrumentation 12, // 6: yagpcc.GPMetrics.spill:type_name -> yagpcc.SpillInfo @@ -2699,11 +2839,12 @@ var file_api_proto_common_yagpcc_metrics_proto_depIdxs = []int32{ 10, // 9: yagpcc.MetricInstrumentation.interconnect:type_name -> yagpcc.InterconnectStat 13, // 10: yagpcc.GpPidProcInfo.proc_stat:type_name -> yagpcc.ProcStat 14, // 11: yagpcc.GpPidProcInfo.proc_status:type_name -> yagpcc.ProcStatus - 12, // [12:12] is the sub-list for method output_type - 12, // [12:12] is the sub-list for method input_type - 12, // [12:12] is the sub-list for extension type_name - 12, // [12:12] is the sub-list for extension extendee - 0, // [0:12] is the sub-list for field type_name + 15, // 12: yagpcc.GpPidProcInfo.proc_io:type_name -> yagpcc.ProcIO + 13, // [13:13] is the sub-list for method output_type + 13, // [13:13] is the sub-list for method input_type + 13, // [13:13] is the sub-list for extension type_name + 13, // [13:13] is the sub-list for extension extendee + 0, // [0:13] is the sub-list for field type_name } func init() { file_api_proto_common_yagpcc_metrics_proto_init() } @@ -2717,7 +2858,7 @@ func file_api_proto_common_yagpcc_metrics_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_api_proto_common_yagpcc_metrics_proto_rawDesc), len(file_api_proto_common_yagpcc_metrics_proto_rawDesc)), NumEnums: 2, - NumMessages: 15, + NumMessages: 16, NumExtensions: 0, NumServices: 0, }, diff --git a/api/proto/common/yagpcc_metrics.proto b/api/proto/common/yagpcc_metrics.proto index ef4ca11..f6eb57e 100644 --- a/api/proto/common/yagpcc_metrics.proto +++ b/api/proto/common/yagpcc_metrics.proto @@ -652,10 +652,10 @@ message ProcStat { int64 starttime = 21; // Virtual memory size in bytes. - int32 vsize = 22; + int64 vsize = 22; // Resident set size in pages. - int32 rss = 23; + int64 rss = 23; // Soft limit in bytes on the rss of the process. int64 rss_limit = 24; @@ -829,9 +829,10 @@ message GpPidProcInfo { // actual data string cmdline = 4; - ProcStat proc_stat = 5; - ProcStatus proc_status = 6; - ProcIO proc_io = 7; + string state = 5; + ProcStat proc_stat = 6; + ProcStatus proc_status = 7; + ProcIO proc_io = 8; } message AggregatedMetrics { diff --git a/api/proto/common/yagpcc_session.pb.go b/api/proto/common/yagpcc_session.pb.go index 19be970..1f0faa6 100644 --- a/api/proto/common/yagpcc_session.pb.go +++ b/api/proto/common/yagpcc_session.pb.go @@ -1,15 +1,15 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.36.11 -// protoc v3.12.4 +// protoc v6.33.4 // source: api/proto/common/yagpcc_session.proto package greenplum import ( - timestamp "github.com/golang/protobuf/ptypes/timestamp" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" unsafe "unsafe" @@ -111,18 +111,18 @@ type SessionInfo struct { ClientPort int64 `protobuf:"varint,7,opt,name=client_port,json=clientPort,proto3" json:"client_port,omitempty"` // backend_start: time backend process was started. // Same as pg_stat_activity.backend_start. - BackendStart *timestamp.Timestamp `protobuf:"bytes,8,opt,name=backend_start,json=backendStart,proto3" json:"backend_start,omitempty"` + BackendStart *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=backend_start,json=backendStart,proto3" json:"backend_start,omitempty"` // xact_start: transaction start time. // If this field is null, it indicates that there is no transaction in progress in the session. // Same as pg_stat_activity.xact_start. - XactStart *timestamp.Timestamp `protobuf:"bytes,9,opt,name=xact_start,json=xactStart,proto3" json:"xact_start,omitempty"` + XactStart *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=xact_start,json=xactStart,proto3" json:"xact_start,omitempty"` // query_start: time query began execution. // If this field is null, it indicates that no query was executed in the session. // Same as pg_stat_activity.query_start. - QueryStart *timestamp.Timestamp `protobuf:"bytes,10,opt,name=query_start,json=queryStart,proto3" json:"query_start,omitempty"` + QueryStart *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=query_start,json=queryStart,proto3" json:"query_start,omitempty"` // state_change: time when the `state` was last changed. // Same as pg_stat_activity.state_change. - StateChange *timestamp.Timestamp `protobuf:"bytes,11,opt,name=state_change,json=stateChange,proto3" json:"state_change,omitempty"` + StateChange *timestamppb.Timestamp `protobuf:"bytes,11,opt,name=state_change,json=stateChange,proto3" json:"state_change,omitempty"` // waiting_reason: reason the session is waiting. // The value can be: lock, replication, or resgroup. // Same as pg_stat_activity.waiting_reason. @@ -249,28 +249,28 @@ func (x *SessionInfo) GetClientPort() int64 { return 0 } -func (x *SessionInfo) GetBackendStart() *timestamp.Timestamp { +func (x *SessionInfo) GetBackendStart() *timestamppb.Timestamp { if x != nil { return x.BackendStart } return nil } -func (x *SessionInfo) GetXactStart() *timestamp.Timestamp { +func (x *SessionInfo) GetXactStart() *timestamppb.Timestamp { if x != nil { return x.XactStart } return nil } -func (x *SessionInfo) GetQueryStart() *timestamp.Timestamp { +func (x *SessionInfo) GetQueryStart() *timestamppb.Timestamp { if x != nil { return x.QueryStart } return nil } -func (x *SessionInfo) GetStateChange() *timestamp.Timestamp { +func (x *SessionInfo) GetStateChange() *timestamppb.Timestamp { if x != nil { return x.StateChange } @@ -388,7 +388,7 @@ type QueryDesc struct { // query_level: level of the query nesting. QueryLevel int64 `protobuf:"varint,4,opt,name=query_level,json=queryLevel,proto3" json:"query_level,omitempty"` // query_start: query start timestamp. - QueryStart *timestamp.Timestamp `protobuf:"bytes,5,opt,name=query_start,json=queryStart,proto3" json:"query_start,omitempty"` + QueryStart *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=query_start,json=queryStart,proto3" json:"query_start,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -451,7 +451,7 @@ func (x *QueryDesc) GetQueryLevel() int64 { return 0 } -func (x *QueryDesc) GetQueryStart() *timestamp.Timestamp { +func (x *QueryDesc) GetQueryStart() *timestamppb.Timestamp { if x != nil { return x.QueryStart } @@ -462,7 +462,7 @@ func (x *QueryDesc) GetQueryStart() *timestamp.Timestamp { type SessionState struct { state protoimpl.MessageState `protogen:"open.v1"` // time: timestamp when statistics was collected. - Time *timestamp.Timestamp `protobuf:"bytes,1,opt,name=time,proto3" json:"time,omitempty"` + Time *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=time,proto3" json:"time,omitempty"` // cluster_id: unique identifier of the cluster. ClusterId string `protobuf:"bytes,2,opt,name=cluster_id,json=clusterId,proto3" json:"cluster_id,omitempty"` // hostname: host name of the master primary host. @@ -529,7 +529,7 @@ func (*SessionState) Descriptor() ([]byte, []int) { return file_api_proto_common_yagpcc_session_proto_rawDescGZIP(), []int{3} } -func (x *SessionState) GetTime() *timestamp.Timestamp { +func (x *SessionState) GetTime() *timestamppb.Timestamp { if x != nil { return x.Time } @@ -737,16 +737,16 @@ func file_api_proto_common_yagpcc_session_proto_rawDescGZIP() []byte { var file_api_proto_common_yagpcc_session_proto_msgTypes = make([]protoimpl.MessageInfo, 4) var file_api_proto_common_yagpcc_session_proto_goTypes = []any{ - (*SessionKey)(nil), // 0: yagpcc.SessionKey - (*SessionInfo)(nil), // 1: yagpcc.SessionInfo - (*QueryDesc)(nil), // 2: yagpcc.QueryDesc - (*SessionState)(nil), // 3: yagpcc.SessionState - (*timestamp.Timestamp)(nil), // 4: google.protobuf.Timestamp - (*QueryKey)(nil), // 5: yagpcc.QueryKey - (*QueryInfo)(nil), // 6: yagpcc.QueryInfo - (QueryStatus)(0), // 7: yagpcc.QueryStatus - (*GPMetrics)(nil), // 8: yagpcc.GPMetrics - (*AggregatedMetrics)(nil), // 9: yagpcc.AggregatedMetrics + (*SessionKey)(nil), // 0: yagpcc.SessionKey + (*SessionInfo)(nil), // 1: yagpcc.SessionInfo + (*QueryDesc)(nil), // 2: yagpcc.QueryDesc + (*SessionState)(nil), // 3: yagpcc.SessionState + (*timestamppb.Timestamp)(nil), // 4: google.protobuf.Timestamp + (*QueryKey)(nil), // 5: yagpcc.QueryKey + (*QueryInfo)(nil), // 6: yagpcc.QueryInfo + (QueryStatus)(0), // 7: yagpcc.QueryStatus + (*GPMetrics)(nil), // 8: yagpcc.GPMetrics + (*AggregatedMetrics)(nil), // 9: yagpcc.AggregatedMetrics } var file_api_proto_common_yagpcc_session_proto_depIdxs = []int32{ 4, // 0: yagpcc.SessionInfo.backend_start:type_name -> google.protobuf.Timestamp diff --git a/go.mod b/go.mod index 6bd499b..248fbcc 100644 --- a/go.mod +++ b/go.mod @@ -4,18 +4,18 @@ go 1.25.5 require ( github.com/afritzler/protoequal v0.1.10 - github.com/alitto/pond v1.9.2 github.com/gofrs/flock v0.13.0 github.com/golang/mock v1.6.0 - github.com/golang/protobuf v1.5.4 github.com/heetch/confita v0.11.0 github.com/jackc/pgx/v4 v4.18.3 github.com/jmoiron/sqlx v1.4.0 github.com/onsi/ginkgo/v2 v2.28.0 github.com/onsi/gomega v1.39.1 github.com/prometheus/client_golang v1.23.2 + github.com/prometheus/procfs v0.16.1 github.com/spf13/pflag v1.0.10 github.com/stretchr/testify v1.11.1 + go.uber.org/mock v0.6.0 go.uber.org/zap v1.27.1 golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa golang.org/x/sync v0.19.0 @@ -46,8 +46,6 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/common v0.66.1 // indirect - github.com/prometheus/procfs v0.16.1 // indirect - go.uber.org/mock v0.6.0 // indirect go.uber.org/multierr v1.10.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect diff --git a/go.sum b/go.sum index 497068e..3a2f12a 100644 --- a/go.sum +++ b/go.sum @@ -7,8 +7,6 @@ github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1 github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/afritzler/protoequal v0.1.10 h1:HRWukWQ6Q0msWv0BwArWJKcjZ1Hz2qFoYlKb1VnzkTg= github.com/afritzler/protoequal v0.1.10/go.mod h1:65ALCt5ghpaRzoWohyRnx88X7o5y6cQwJmOb9yzdheg= -github.com/alitto/pond v1.9.2 h1:9Qb75z/scEZVCoSU+osVmQ0I0JOeLfdTDafrbcJ8CLs= -github.com/alitto/pond v1.9.2/go.mod h1:xQn3P/sHTYcU/1BR3i86IGIrilcrGC2LiS+E2+CJWsI= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= diff --git a/internal/grpc/get_query_info.go b/internal/grpc/get_query_info.go index 28686f8..7e94a96 100644 --- a/internal/grpc/get_query_info.go +++ b/internal/grpc/get_query_info.go @@ -2,6 +2,7 @@ package grpc import ( "context" + "errors" "fmt" "time" @@ -23,6 +24,47 @@ type GetQueryInfoServer struct { RQStorage *storage.RunningQueriesStorage } +func (s *GetQueryInfoServer) GetPidProcStat(ctx context.Context, in *pb.GetPidProcInfoReq) (*pb.GetPidProcInfoResponse, error) { + s.Logger.Debugf("got get pid info request %v", in) + start := time.Now() + + pidResponse := &pb.GetPidProcInfoResponse{} + nErrors := 0 + lastError := error(nil) + + if in != nil && in.SegmentProcess != nil { + for _, segProcess := range in.SegmentProcess { + pidStat, err := utils.GetPidProcInfo(segProcess.Pid, segProcess.GpSegmentId, segProcess.SessId) + if err != nil { + if errors.Is(err, utils.ErrProcessNotFound) { + s.Logger.Debugf("pid %d not found: %v", segProcess.Pid, err) + continue + } + s.Logger.Debugf("got error while getting pid info %v for %v", err, segProcess) + nErrors++ + lastError = err + continue + } + pidResponse.PidProcData = append(pidResponse.PidProcData, pidStat) + } + } + + if lastError != nil { + s.Logger.Infof("got %v errors in pid request, the last error is %v", nErrors, lastError) + } + + if metrics.YagpccMetrics != nil { + metrics.YagpccMetrics.HandleLatencies.With(map[string]string{"method": "GpPidProcInfo"}).Observe(time.Since(start).Seconds()) + } + + if nErrors > 0 && len(pidResponse.PidProcData) == 0 { + // something got totally wrong + return nil, lastError + } + + return pidResponse, nil +} + func (s *GetQueryInfoServer) GetMetricQueries(ctx context.Context, in *pb.GetQueriesInfoReq) (*pb.GetQueriesInfoResponse, error) { s.Logger.Debugf("got get data request %v", in) start := time.Now() diff --git a/internal/grpc/get_query_info_linux_test.go b/internal/grpc/get_query_info_linux_test.go new file mode 100644 index 0000000..3975ffb --- /dev/null +++ b/internal/grpc/get_query_info_linux_test.go @@ -0,0 +1,68 @@ +package grpc_test + +import ( + "context" + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + pb "github.com/open-gpdb/yagpcc/api/proto/agent_segment" +) + +func TestGpPidProcInfo_CurrentProcess(t *testing.T) { + server := newTestGetQueryInfoServer(t) + pid := int64(os.Getpid()) + + resp, err := server.GetPidProcStat(context.Background(), &pb.GetPidProcInfoReq{ + SegmentProcess: []*pb.SegmentProcess{ + {GpSegmentId: 7, SessId: 42, Pid: pid}, + }, + }) + + require.NoError(t, err) + require.NotNil(t, resp) + require.Len(t, resp.PidProcData, 1) + + info := resp.PidProcData[0] + require.NotNil(t, info) + assert.Equal(t, int64(7), info.GpSegmentId) + assert.Equal(t, int64(42), info.SessId) + assert.Equal(t, pid, info.Pid) + assert.NotEmpty(t, info.Cmdline) + + require.NotNil(t, info.ProcStat) + assert.Equal(t, int32(pid), info.ProcStat.Pid) + assert.NotEmpty(t, info.ProcStat.Comm) + assert.NotEmpty(t, info.ProcStat.State) + + require.NotNil(t, info.ProcStatus) + assert.Equal(t, int32(pid), info.ProcStatus.Pid) + assert.NotEmpty(t, info.ProcStatus.Name) +} + +func TestGpPidProcInfo_MixExistingAndNonExistentPids(t *testing.T) { + server := newTestGetQueryInfoServer(t) + pid := int64(os.Getpid()) + + resp, err := server.GetPidProcStat(context.Background(), &pb.GetPidProcInfoReq{ + SegmentProcess: []*pb.SegmentProcess{ + {GpSegmentId: 0, SessId: 10, Pid: 4194305000000}, // non-existent + {GpSegmentId: 1, SessId: 20, Pid: pid}, // current process + {GpSegmentId: 2, SessId: 30, Pid: 4194305000001}, // non-existent + }, + }) + + require.NoError(t, err) + require.NotNil(t, resp) + // Only the existing PID should produce a result; non-existent ones are skipped. + require.Len(t, resp.PidProcData, 1) + + info := resp.PidProcData[0] + require.NotNil(t, info) + assert.Equal(t, int64(1), info.GpSegmentId) + assert.Equal(t, int64(20), info.SessId) + assert.Equal(t, pid, info.Pid) + assert.NotEmpty(t, info.Cmdline) +} diff --git a/internal/grpc/get_query_info_test.go b/internal/grpc/get_query_info_test.go index e7eceb5..8b27dd8 100644 --- a/internal/grpc/get_query_info_test.go +++ b/internal/grpc/get_query_info_test.go @@ -2,6 +2,7 @@ package grpc_test import ( "context" + "os" "sort" "testing" "time" @@ -12,6 +13,8 @@ import ( pb "github.com/open-gpdb/yagpcc/api/proto/agent_segment" pbc "github.com/open-gpdb/yagpcc/api/proto/common" + "github.com/open-gpdb/yagpcc/internal/grpc" + "github.com/open-gpdb/yagpcc/internal/utils" ) func TestFilterMessages(t *testing.T) { @@ -324,3 +327,87 @@ func TestDeleteCompleted(t *testing.T) { assertQueriesInfoResponseEqual(t, &pb.GetQueriesInfoResponse{}, response) }) } + +// newTestGetQueryInfoServer creates a GetQueryInfoServer with a logger suitable for tests. +func newTestGetQueryInfoServer(t *testing.T) *grpc.GetQueryInfoServer { + t.Helper() + file, err := os.CreateTemp(t.TempDir(), "trace-*.log") + require.NoError(t, err) + t.Cleanup(func() { + _ = file.Close() + }) + zLogger := utils.DualLog(true, file) + return &grpc.GetQueryInfoServer{ + Logger: zLogger, + MaxMessageSize: 100 * 1024 * 1024, + } +} + +func TestGpPidProcInfo_NilRequest(t *testing.T) { + server := newTestGetQueryInfoServer(t) + + resp, err := server.GetPidProcStat(context.Background(), nil) + + require.NoError(t, err) + require.NotNil(t, resp) + assert.Empty(t, resp.PidProcData) +} + +func TestGpPidProcInfo_EmptySegmentProcess(t *testing.T) { + server := newTestGetQueryInfoServer(t) + + resp, err := server.GetPidProcStat(context.Background(), &pb.GetPidProcInfoReq{ + SegmentProcess: []*pb.SegmentProcess{}, + }) + + require.NoError(t, err) + require.NotNil(t, resp) + assert.Empty(t, resp.PidProcData) +} + +func TestGpPidProcInfo_NilSegmentProcess(t *testing.T) { + server := newTestGetQueryInfoServer(t) + + resp, err := server.GetPidProcStat(context.Background(), &pb.GetPidProcInfoReq{ + SegmentProcess: nil, + }) + + require.NoError(t, err) + require.NotNil(t, resp) + assert.Empty(t, resp.PidProcData) +} + +func TestGpPidProcInfo_NonExistentPids(t *testing.T) { + server := newTestGetQueryInfoServer(t) + + // PIDs that are guaranteed not to exist. + resp, err := server.GetPidProcStat(context.Background(), &pb.GetPidProcInfoReq{ + SegmentProcess: []*pb.SegmentProcess{ + {GpSegmentId: 1, SessId: 10, Pid: 4194305000000}, + {GpSegmentId: 2, SessId: 20, Pid: 4194305000001}, + }, + }) + + // Non-existent PIDs return ErrProcessNotFound from GetPidProcInfo and are + // skipped (not appended), so the response should be empty. + require.NoError(t, err) + require.NotNil(t, resp) + assert.Empty(t, resp.PidProcData, "non-existent PIDs should be skipped") +} + +func TestGpPidProcInfo_MultipleSegmentProcesses(t *testing.T) { + server := newTestGetQueryInfoServer(t) + + // Multiple non-existent PIDs — all should be skipped. + resp, err := server.GetPidProcStat(context.Background(), &pb.GetPidProcInfoReq{ + SegmentProcess: []*pb.SegmentProcess{ + {GpSegmentId: 0, SessId: 100, Pid: 4194305000000}, + {GpSegmentId: 1, SessId: 200, Pid: 4194305000001}, + {GpSegmentId: 2, SessId: 300, Pid: 4194305000002}, + }, + }) + + require.NoError(t, err) + require.NotNil(t, resp) + assert.Empty(t, resp.PidProcData, "all non-existent PIDs should be skipped") +} diff --git a/internal/utils/procfs.go b/internal/utils/procfs.go new file mode 100644 index 0000000..867cb4c --- /dev/null +++ b/internal/utils/procfs.go @@ -0,0 +1,226 @@ +package utils + +import ( + "errors" + "fmt" + "math" + "os" + "strings" + "syscall" + + "github.com/prometheus/procfs" + + pb "github.com/open-gpdb/yagpcc/api/proto/common" +) + +// ErrProcessNotFound is returned by GetPidProcInfo when the target PID does +// not exist, has already exited, or falls outside the valid PID range. +// Callers should check for this error with errors.Is and handle it +// accordingly (e.g. skip the PID, log at debug level, increment a counter). +var ErrProcessNotFound = errors.New("process not found") + +// ParseCmdLineSessionStatus extracts the session status from a +// PostgreSQL/Greenplum backend process cmdline string (as seen in `ps` output +// or read from /proc//cmdline). +// +// Session backend cmdlines contain " con cmd " at the end, +// for example: +// +// postgres: 5432, gpadmin postgres localhost(33326) con21 cmd237786 idle +// postgres: 5432, monitor postgres localhost(22122) con38 cmd1006767 SELECT +// +// The function returns the status portion (e.g. "idle", "SELECT") or an +// empty string when the cmdline does not belong to a session backend +// (background processes like "checkpointer process", "bgworker: …", etc.). +func ParseCmdLineSessionStatus(cmdline string) string { + // Session cmdlines always contain " cmd" followed by a number and the status. + cmdIdx := strings.LastIndex(cmdline, " cmd") + if cmdIdx == -1 { + return "" + } + + // Verify this is a session line by also checking for " con". + if !strings.Contains(cmdline, " con") { + return "" + } + + // After " cmd" we expect " ". + // Find the first space after "cmd" to locate the status. + afterCmd := cmdline[cmdIdx+4:] // skip " cmd" + spaceIdx := strings.IndexByte(afterCmd, ' ') + if spaceIdx == -1 { + return "" + } + + status := strings.TrimSpace(afterCmd[spaceIdx+1:]) + return status +} + +// GetPidProcInfo reads /proc//{stat,status,cmdline,io} via procfs and +// returns a populated GpPidProcInfo protobuf message. +// gpSegmentID and sessID are pass-through identifiers written into the +// returned message so the caller can correlate the result with a +// Greenplum backend. +// +// If the process does not exist (or disappears mid-read) the function +// returns an error wrapping ErrProcessNotFound. Callers should use +// errors.Is(err, ErrProcessNotFound) to distinguish vanished PIDs from +// unexpected failures. +func GetPidProcInfo(pid int64, gpSegmentID, sessID int64) (*pb.GpPidProcInfo, error) { + // Guard against int64 values that cannot be represented as a platform-native + // int (required by procfs.NewProc). On 32-bit systems int is 32 bits wide, so + // an int64 PID larger than math.MaxInt would overflow on conversion. PIDs + // outside the valid range (1 … math.MaxInt) cannot correspond to a real OS + // process. + if pid <= 0 || pid > math.MaxInt { + return nil, fmt.Errorf("pid %d out of valid range: %w", pid, ErrProcessNotFound) + } + proc, err := procfs.NewProc(int(pid)) + if err != nil { + if isProcessGone(err) { + return nil, fmt.Errorf("pid %d: %w", pid, ErrProcessNotFound) + } + return nil, err + } + + return getProcInfo(proc, pid, gpSegmentID, sessID) +} + +// getProcInfo reads /proc//{stat,status,cmdline,io} from the given +// procfs.Proc handle and returns a populated GpPidProcInfo protobuf message. +// It is separated from GetPidProcInfo to allow testing with a fake procfs +// directory. +func getProcInfo(proc procfs.Proc, pid, gpSegmentID, sessID int64) (*pb.GpPidProcInfo, error) { + info := &pb.GpPidProcInfo{ + GpSegmentId: gpSegmentID, + SessId: sessID, + Pid: pid, + } + + // /proc//cmdline + if cmdline, err := proc.CmdLine(); err == nil { + info.Cmdline = strings.Join(cmdline, " ") + info.State = ParseCmdLineSessionStatus(info.Cmdline) + } else if !isProcessGone(err) { + return nil, err + } + + // /proc//stat + if stat, err := proc.Stat(); err == nil { + info.ProcStat = convertProcStat(&stat) + } else if !isProcessGone(err) { + return nil, err + } + + // /proc//status + if status, err := proc.NewStatus(); err == nil { + info.ProcStatus = convertProcStatus(&status) + } else if !isProcessGone(err) { + return nil, err + } + + // /proc//io + if pio, err := proc.IO(); err == nil { + info.ProcIo = convertProcIO(&pio) + } else if !isProcessGone(err) { + return nil, err + } + + return info, nil +} + +// isProcessGone returns true when the error indicates the target PID +// no longer exists (ENOENT / ESRCH or errors wrapping them). +func isProcessGone(err error) bool { + return errors.Is(err, os.ErrNotExist) || errors.Is(err, syscall.ESRCH) +} + +// convertProcStat maps prometheus/procfs.ProcStat → protobuf ProcStat. +func convertProcStat(s *procfs.ProcStat) *pb.ProcStat { + return &pb.ProcStat{ + Pid: int32(s.PID), + Comm: s.Comm, + State: s.State, + Ppid: int32(s.PPID), + Pgrp: int32(s.PGRP), + Session: int32(s.Session), + Tty: int32(s.TTY), + Tpgid: int32(s.TPGID), + Flags: int32(s.Flags), + MinFlt: int32(s.MinFlt), + CminFlt: int32(s.CMinFlt), + MajFlt: int32(s.MajFlt), + CmajFlt: int32(s.CMajFlt), + Utime: int32(s.UTime), + Stime: int32(s.STime), + Cutime: int32(s.CUTime), + Cstime: int32(s.CSTime), + Priority: int32(s.Priority), + Nice: int32(s.Nice), + NumThreads: int32(s.NumThreads), + Starttime: int64(s.Starttime), + Vsize: int64(s.VSize), + Rss: int64(s.RSS), + RssLimit: int64(s.RSSLimit), + Processor: int32(s.Processor), + RtPriority: int32(s.RTPriority), + Policy: int32(s.Policy), + DelayAcctBlkIoTicks: int64(s.DelayAcctBlkIOTicks), + GuestTime: int32(s.GuestTime), + CguestTime: int32(s.CGuestTime), + } +} + +// convertProcStatus maps prometheus/procfs.ProcStatus → protobuf ProcStatus. +func convertProcStatus(s *procfs.ProcStatus) *pb.ProcStatus { + return &pb.ProcStatus{ + Pid: int32(s.PID), + Name: s.Name, + Tgid: int32(s.TGID), + NsPids: uint64SliceToInt64(s.NSpids), + VmPeak: int64(s.VmPeak), + VmSize: int64(s.VmSize), + VmLck: int64(s.VmLck), + VmPin: int64(s.VmPin), + VmHwm: int64(s.VmHWM), + VmRss: int64(s.VmRSS), + RssAnon: int64(s.RssAnon), + RssFile: int64(s.RssFile), + RssShmem: int64(s.RssShmem), + VmData: int64(s.VmData), + VmStk: int64(s.VmStk), + VmExe: int64(s.VmExe), + VmLib: int64(s.VmLib), + VmPte: int64(s.VmPTE), + VmPmd: int64(s.VmPMD), + VmSwap: int64(s.VmSwap), + HugetlbPages: int64(s.HugetlbPages), + VoluntaryCtxtSwitches: int64(s.VoluntaryCtxtSwitches), + NonVoluntaryCtxtSwitches: int64(s.NonVoluntaryCtxtSwitches), + Uids: uint64SliceToInt64(s.UIDs[:]), + Gids: uint64SliceToInt64(s.GIDs[:]), + CpusAllowedList: uint64SliceToInt64(s.CpusAllowedList), + } +} + +// convertProcIO maps prometheus/procfs.ProcIO → protobuf ProcIO. +func convertProcIO(io *procfs.ProcIO) *pb.ProcIO { + return &pb.ProcIO{ + Rchar: int64(io.RChar), + Wchar: int64(io.WChar), + Syscr: int64(io.SyscR), + Syscw: int64(io.SyscW), + ReadBytes: int64(io.ReadBytes), + WriteBytes: int64(io.WriteBytes), + CancelledWriteBytes: io.CancelledWriteBytes, + } +} + +// uint64SliceToInt64 converts a []uint64 to []int64. +func uint64SliceToInt64(src []uint64) []int64 { + dst := make([]int64, len(src)) + for i, v := range src { + dst[i] = int64(v) + } + return dst +} diff --git a/internal/utils/procfs_getprocinfo_test.go b/internal/utils/procfs_getprocinfo_test.go new file mode 100644 index 0000000..ab0de7d --- /dev/null +++ b/internal/utils/procfs_getprocinfo_test.go @@ -0,0 +1,401 @@ +package utils + +import ( + "fmt" + "os" + "path/filepath" + "strconv" + "testing" + + "github.com/prometheus/procfs" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// fakeProcDir is a helper that creates a temporary directory mimicking +// /proc// with the given file contents. Files with nil content are +// skipped (simulating a missing proc file). +type fakeProcDir struct { + root string + pid int +} + +func newFakeProcDir(t *testing.T, pid int) *fakeProcDir { + t.Helper() + root := t.TempDir() + pidDir := filepath.Join(root, strconv.Itoa(pid)) + require.NoError(t, os.MkdirAll(pidDir, 0o755)) + return &fakeProcDir{root: root, pid: pid} +} + +func (f *fakeProcDir) writeFile(t *testing.T, name, content string) { + t.Helper() + path := filepath.Join(f.root, strconv.Itoa(f.pid), name) + require.NoError(t, os.WriteFile(path, []byte(content), 0o644)) +} + +func (f *fakeProcDir) proc(t *testing.T) procfs.Proc { + t.Helper() + fs, err := procfs.NewFS(f.root) + require.NoError(t, err) + p, err := fs.Proc(f.pid) + require.NoError(t, err) + return p +} + +// sampleStat returns a realistic /proc//stat line for the given PID. +// Format matches what the Linux kernel writes to /proc//stat. +func sampleStat(pid int) string { + // Fields: pid (comm) state ppid pgrp session tty tpgid flags minflt cminflt + // majflt cmajflt utime stime cutime cstime priority nice num_threads + // itrealvalue starttime vsize rss rsslimit startcode endcode startstack + // kstkesp kstkeip signal blocked sigignore sigcatch wchan nswap cnswap + // exit_signal processor rt_priority policy delayacct_blkio_ticks guest_time + // cguest_time + return fmt.Sprintf("%d (postgres) S 1 %d %d 0 -1 4194304 100 10 5 1 500 200 50 20 20 0 4 0 123456789 1048576 256 18446744073709551615 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 100 0 0 0 0 0 0 0 0 0 0", + pid, pid, pid) +} + +// sampleStatus returns a realistic /proc//status content. +func sampleStatus(pid int) string { + return fmt.Sprintf(`Name: postgres +Umask: 0022 +State: S (sleeping) +Tgid: %d +Ngid: 0 +Pid: %d +PPid: 1 +TracerPid: 0 +Uid: 1000 1000 1000 1000 +Gid: 100 100 100 100 +FDSize: 256 +NStgid: %d +NSpid: %d +VmPeak: 2048 kB +VmSize: 1024 kB +VmLck: 0 kB +VmPin: 0 kB +VmHWM: 512 kB +VmRSS: 256 kB +RssAnon: 128 kB +RssFile: 64 kB +RssShmem: 64 kB +VmData: 100 kB +VmStk: 8 kB +VmExe: 4 kB +VmLib: 50 kB +VmPTE: 1 kB +VmPMD: 0 kB +VmSwap: 0 kB +HugetlbPages: 0 kB +voluntary_ctxt_switches: 1000 +nonvoluntary_ctxt_switches: 50 +Cpus_allowed_list: 0-3`, pid, pid, pid, pid) +} + +// sampleIO returns a realistic /proc//io content. +func sampleIO() string { + return `rchar: 1000000 +wchar: 500000 +syscr: 200 +syscw: 100 +read_bytes: 4096000 +write_bytes: 2048000 +cancelled_write_bytes: 512 +` +} + +func TestGetProcInfo_AllFiles(t *testing.T) { + const pid = 42 + fake := newFakeProcDir(t, pid) + + // Session backend cmdline with "idle" status. + cmdline := "postgres: 5432, gpadmin postgres localhost(33326) con21 cmd237786 idle" + fake.writeFile(t, "cmdline", cmdline) + fake.writeFile(t, "stat", sampleStat(pid)) + fake.writeFile(t, "status", sampleStatus(pid)) + fake.writeFile(t, "io", sampleIO()) + + proc := fake.proc(t) + info, err := getProcInfo(proc, int64(pid), 7, 100) + + require.NoError(t, err) + require.NotNil(t, info) + + // Pass-through fields. + assert.Equal(t, int64(7), info.GpSegmentId) + assert.Equal(t, int64(100), info.SessId) + assert.Equal(t, int64(pid), info.Pid) + + // Cmdline and state extraction. + assert.Equal(t, cmdline, info.Cmdline) + assert.Equal(t, "idle", info.State) + + // ProcStat populated. + require.NotNil(t, info.ProcStat) + assert.Equal(t, int32(pid), info.ProcStat.Pid) + assert.Equal(t, "postgres", info.ProcStat.Comm) + assert.Equal(t, "S", info.ProcStat.State) + assert.Equal(t, int32(1), info.ProcStat.Ppid) + assert.Equal(t, int32(4), info.ProcStat.NumThreads) + assert.Equal(t, int64(123456789), info.ProcStat.Starttime) + assert.Equal(t, int64(1048576), info.ProcStat.Vsize) + assert.Equal(t, int64(256), info.ProcStat.Rss) + assert.Equal(t, int32(500), info.ProcStat.Utime) + assert.Equal(t, int32(200), info.ProcStat.Stime) + assert.Equal(t, int32(3), info.ProcStat.Processor) + assert.Equal(t, int64(100), info.ProcStat.DelayAcctBlkIoTicks) + + // ProcStatus populated. + require.NotNil(t, info.ProcStatus) + assert.Equal(t, int32(pid), info.ProcStatus.Pid) + assert.Equal(t, "postgres", info.ProcStatus.Name) + assert.Equal(t, int32(pid), info.ProcStatus.Tgid) + assert.Equal(t, int64(2048*1024), info.ProcStatus.VmPeak) + assert.Equal(t, int64(1024*1024), info.ProcStatus.VmSize) + assert.Equal(t, int64(512*1024), info.ProcStatus.VmHwm) + assert.Equal(t, int64(256*1024), info.ProcStatus.VmRss) + assert.Equal(t, int64(128*1024), info.ProcStatus.RssAnon) + assert.Equal(t, int64(64*1024), info.ProcStatus.RssFile) + assert.Equal(t, int64(64*1024), info.ProcStatus.RssShmem) + assert.Equal(t, int64(1000), info.ProcStatus.VoluntaryCtxtSwitches) + assert.Equal(t, int64(50), info.ProcStatus.NonVoluntaryCtxtSwitches) + assert.Equal(t, []int64{1000, 1000, 1000, 1000}, info.ProcStatus.Uids) + assert.Equal(t, []int64{100, 100, 100, 100}, info.ProcStatus.Gids) + assert.Equal(t, []int64{0, 1, 2, 3}, info.ProcStatus.CpusAllowedList) + + // ProcIO populated. + require.NotNil(t, info.ProcIo) + assert.Equal(t, int64(1000000), info.ProcIo.Rchar) + assert.Equal(t, int64(500000), info.ProcIo.Wchar) + assert.Equal(t, int64(200), info.ProcIo.Syscr) + assert.Equal(t, int64(100), info.ProcIo.Syscw) + assert.Equal(t, int64(4096000), info.ProcIo.ReadBytes) + assert.Equal(t, int64(2048000), info.ProcIo.WriteBytes) + assert.Equal(t, int64(512), info.ProcIo.CancelledWriteBytes) +} + +func TestGetProcInfo_SessionStateExtraction(t *testing.T) { + tests := []struct { + name string + cmdline string + expectedState string + }{ + { + name: "idle session", + cmdline: "postgres: 5432, gpadmin postgres localhost(33326) con21 cmd237786 idle", + expectedState: "idle", + }, + { + name: "SELECT query", + cmdline: "postgres: 5432, monitor postgres localhost(22122) con38 cmd1006767 SELECT", + expectedState: "SELECT", + }, + { + name: "background process has no state", + cmdline: "postgres: 5432, checkpointer process", + expectedState: "", + }, + { + name: "empty cmdline", + cmdline: "", + expectedState: "", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + const pid = 99 + fake := newFakeProcDir(t, pid) + fake.writeFile(t, "cmdline", tt.cmdline) + fake.writeFile(t, "stat", sampleStat(pid)) + fake.writeFile(t, "status", sampleStatus(pid)) + fake.writeFile(t, "io", sampleIO()) + + proc := fake.proc(t) + info, err := getProcInfo(proc, int64(pid), 1, 1) + + require.NoError(t, err) + require.NotNil(t, info) + assert.Equal(t, tt.expectedState, info.State) + }) + } +} + +func TestGetProcInfo_MissingCmdline(t *testing.T) { + const pid = 10 + fake := newFakeProcDir(t, pid) + // No cmdline file written. + fake.writeFile(t, "stat", sampleStat(pid)) + fake.writeFile(t, "status", sampleStatus(pid)) + fake.writeFile(t, "io", sampleIO()) + + proc := fake.proc(t) + info, err := getProcInfo(proc, int64(pid), 2, 200) + + require.NoError(t, err) + require.NotNil(t, info) + + // Cmdline and state should be empty when file is missing. + assert.Empty(t, info.Cmdline) + assert.Empty(t, info.State) + + // Other fields should still be populated. + require.NotNil(t, info.ProcStat) + assert.Equal(t, int32(pid), info.ProcStat.Pid) + require.NotNil(t, info.ProcStatus) + assert.Equal(t, int32(pid), info.ProcStatus.Pid) + require.NotNil(t, info.ProcIo) +} + +func TestGetProcInfo_MissingStat(t *testing.T) { + const pid = 11 + fake := newFakeProcDir(t, pid) + fake.writeFile(t, "cmdline", "postgres: 5432, gpadmin postgres localhost(33326) con21 cmd1 idle") + // No stat file written. + fake.writeFile(t, "status", sampleStatus(pid)) + fake.writeFile(t, "io", sampleIO()) + + proc := fake.proc(t) + info, err := getProcInfo(proc, int64(pid), 3, 300) + + require.NoError(t, err) + require.NotNil(t, info) + + // Cmdline should be populated. + assert.NotEmpty(t, info.Cmdline) + assert.Equal(t, "idle", info.State) + + // ProcStat should be nil when stat file is missing. + assert.Nil(t, info.ProcStat) + + // Other fields should still be populated. + require.NotNil(t, info.ProcStatus) + require.NotNil(t, info.ProcIo) +} + +func TestGetProcInfo_MissingStatus(t *testing.T) { + const pid = 12 + fake := newFakeProcDir(t, pid) + fake.writeFile(t, "cmdline", "postgres: 5432, gpadmin postgres localhost(33326) con21 cmd1 idle") + fake.writeFile(t, "stat", sampleStat(pid)) + // No status file written. + fake.writeFile(t, "io", sampleIO()) + + proc := fake.proc(t) + info, err := getProcInfo(proc, int64(pid), 4, 400) + + require.NoError(t, err) + require.NotNil(t, info) + + assert.NotEmpty(t, info.Cmdline) + require.NotNil(t, info.ProcStat) + + // ProcStatus should be nil when status file is missing. + assert.Nil(t, info.ProcStatus) + + require.NotNil(t, info.ProcIo) +} + +func TestGetProcInfo_MissingIO(t *testing.T) { + const pid = 13 + fake := newFakeProcDir(t, pid) + fake.writeFile(t, "cmdline", "postgres: 5432, gpadmin postgres localhost(33326) con21 cmd1 idle") + fake.writeFile(t, "stat", sampleStat(pid)) + fake.writeFile(t, "status", sampleStatus(pid)) + // No io file written. + + proc := fake.proc(t) + info, err := getProcInfo(proc, int64(pid), 5, 500) + + require.NoError(t, err) + require.NotNil(t, info) + + assert.NotEmpty(t, info.Cmdline) + require.NotNil(t, info.ProcStat) + require.NotNil(t, info.ProcStatus) + + // ProcIO should be nil when io file is missing. + assert.Nil(t, info.ProcIo) +} + +func TestGetProcInfo_AllFilesMissing(t *testing.T) { + const pid = 14 + fake := newFakeProcDir(t, pid) + // No files written at all — simulates a process that exists in the + // directory listing but whose proc files have all vanished. + + proc := fake.proc(t) + info, err := getProcInfo(proc, int64(pid), 6, 600) + + require.NoError(t, err) + require.NotNil(t, info) + + // Pass-through fields should still be set. + assert.Equal(t, int64(6), info.GpSegmentId) + assert.Equal(t, int64(600), info.SessId) + assert.Equal(t, int64(pid), info.Pid) + + // All proc data should be nil/empty. + assert.Empty(t, info.Cmdline) + assert.Empty(t, info.State) + assert.Nil(t, info.ProcStat) + assert.Nil(t, info.ProcStatus) + assert.Nil(t, info.ProcIo) +} + +func TestGetProcInfo_PassThroughFields(t *testing.T) { + // Verify that gpSegmentID and sessID are correctly passed through + // for various values including zero and negative. + tests := []struct { + name string + gpSegmentID int64 + sessID int64 + }{ + {"positive values", 7, 42}, + {"zero values", 0, 0}, + {"negative segment", -1, 100}, + {"large values", 999999, 888888}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + const pid = 15 + fake := newFakeProcDir(t, pid) + fake.writeFile(t, "cmdline", "test") + fake.writeFile(t, "stat", sampleStat(pid)) + fake.writeFile(t, "status", sampleStatus(pid)) + fake.writeFile(t, "io", sampleIO()) + + proc := fake.proc(t) + info, err := getProcInfo(proc, int64(pid), tt.gpSegmentID, tt.sessID) + + require.NoError(t, err) + require.NotNil(t, info) + assert.Equal(t, tt.gpSegmentID, info.GpSegmentId) + assert.Equal(t, tt.sessID, info.SessId) + assert.Equal(t, int64(pid), info.Pid) + }) + } +} + +func TestGetProcInfo_MultiWordCmdline(t *testing.T) { + // procfs cmdline uses null bytes as separators; the function joins them + // with spaces. + const pid = 16 + fake := newFakeProcDir(t, pid) + // Simulate a cmdline with null-separated arguments. + fake.writeFile(t, "cmdline", "/usr/bin/postgres\x00-D\x00/data") + fake.writeFile(t, "stat", sampleStat(pid)) + fake.writeFile(t, "status", sampleStatus(pid)) + fake.writeFile(t, "io", sampleIO()) + + proc := fake.proc(t) + info, err := getProcInfo(proc, int64(pid), 1, 1) + + require.NoError(t, err) + require.NotNil(t, info) + assert.Equal(t, "/usr/bin/postgres -D /data", info.Cmdline) + // Not a session cmdline, so state should be empty. + assert.Empty(t, info.State) +} diff --git a/internal/utils/procfs_linux_test.go b/internal/utils/procfs_linux_test.go new file mode 100644 index 0000000..438dcf6 --- /dev/null +++ b/internal/utils/procfs_linux_test.go @@ -0,0 +1,41 @@ +package utils + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestGetPidProcInfo_CurrentProcess(t *testing.T) { + pid := int64(os.Getpid()) + info, err := GetPidProcInfo(pid, 7, 42) + + require.NoError(t, err) + require.NotNil(t, info) + + assert.Equal(t, int64(7), info.GpSegmentId) + assert.Equal(t, int64(42), info.SessId) + assert.Equal(t, pid, info.Pid) + assert.NotEmpty(t, info.Cmdline) + + require.NotNil(t, info.ProcStat) + assert.Equal(t, int32(pid), info.ProcStat.Pid) + assert.NotEmpty(t, info.ProcStat.Comm) + assert.NotEmpty(t, info.ProcStat.State) + assert.Greater(t, info.ProcStat.NumThreads, int32(0)) + + require.NotNil(t, info.ProcStatus) + assert.Equal(t, int32(pid), info.ProcStatus.Pid) + assert.NotEmpty(t, info.ProcStatus.Name) + assert.Greater(t, info.ProcStatus.VmSize, int64(0)) + assert.Greater(t, info.ProcStatus.VmRss, int64(0)) + + require.NotNil(t, info.ProcIo) + // The current process must have read at least something (the test binary itself). + assert.GreaterOrEqual(t, info.ProcIo.Rchar, int64(0)) + assert.GreaterOrEqual(t, info.ProcIo.Wchar, int64(0)) + assert.GreaterOrEqual(t, info.ProcIo.Syscr, int64(0)) + assert.GreaterOrEqual(t, info.ProcIo.Syscw, int64(0)) +} diff --git a/internal/utils/procfs_test.go b/internal/utils/procfs_test.go new file mode 100644 index 0000000..5003ebd --- /dev/null +++ b/internal/utils/procfs_test.go @@ -0,0 +1,326 @@ +package utils + +import ( + "errors" + "fmt" + "os" + "syscall" + "testing" + + "github.com/prometheus/procfs" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestIsProcessGone(t *testing.T) { + t.Run("nil error", func(t *testing.T) { + assert.False(t, isProcessGone(nil)) + }) + + t.Run("no such process", func(t *testing.T) { + assert.True(t, isProcessGone(fmt.Errorf("open /proc/999999/stat: %w", syscall.ESRCH))) + }) + + t.Run("no such file or directory", func(t *testing.T) { + assert.True(t, isProcessGone(fmt.Errorf("open /proc/999999/stat: %w", os.ErrNotExist))) + }) + + t.Run("other error", func(t *testing.T) { + assert.False(t, isProcessGone(errors.New("permission denied"))) + }) +} + +func TestConvertProcStat(t *testing.T) { + src := &procfs.ProcStat{ + PID: 42, + Comm: "postgres", + State: "S", + PPID: 1, + PGRP: 42, + Session: 42, + TTY: 0, + TPGID: -1, + Flags: 0x00400000, + MinFlt: 100, + CMinFlt: 10, + MajFlt: 5, + CMajFlt: 1, + UTime: 500, + STime: 200, + CUTime: 50, + CSTime: 20, + Priority: 20, + Nice: 0, + NumThreads: 4, + Starttime: 123456789, + VSize: 1048576, + RSS: 256, + RSSLimit: 18446744073709551615, + Processor: 3, + RTPriority: 0, + Policy: 0, + DelayAcctBlkIOTicks: 100, + GuestTime: 0, + CGuestTime: 0, + } + + result := convertProcStat(src) + + require.NotNil(t, result) + assert.Equal(t, int32(42), result.Pid) + assert.Equal(t, "postgres", result.Comm) + assert.Equal(t, "S", result.State) + assert.Equal(t, int32(1), result.Ppid) + assert.Equal(t, int32(42), result.Pgrp) + assert.Equal(t, int32(42), result.Session) + assert.Equal(t, int32(0), result.Tty) + assert.Equal(t, int32(-1), result.Tpgid) + assert.Equal(t, int32(0x00400000), result.Flags) + assert.Equal(t, int32(100), result.MinFlt) + assert.Equal(t, int32(10), result.CminFlt) + assert.Equal(t, int32(5), result.MajFlt) + assert.Equal(t, int32(1), result.CmajFlt) + assert.Equal(t, int32(500), result.Utime) + assert.Equal(t, int32(200), result.Stime) + assert.Equal(t, int32(50), result.Cutime) + assert.Equal(t, int32(20), result.Cstime) + assert.Equal(t, int32(20), result.Priority) + assert.Equal(t, int32(0), result.Nice) + assert.Equal(t, int32(4), result.NumThreads) + assert.Equal(t, int64(123456789), result.Starttime) + assert.Equal(t, int64(1048576), result.Vsize) + assert.Equal(t, int64(256), result.Rss) + assert.Equal(t, int64(-1), result.RssLimit) + assert.Equal(t, int32(3), result.Processor) + assert.Equal(t, int32(0), result.RtPriority) + assert.Equal(t, int32(0), result.Policy) + assert.Equal(t, int64(100), result.DelayAcctBlkIoTicks) + assert.Equal(t, int32(0), result.GuestTime) + assert.Equal(t, int32(0), result.CguestTime) +} + +func TestConvertProcStatus(t *testing.T) { + src := &procfs.ProcStatus{ + PID: 42, + Name: "postgres", + TGID: 42, + NSpids: []uint64{42, 1}, + VmPeak: 2048000, + VmSize: 1024000, + VmLck: 0, + VmPin: 0, + VmHWM: 512000, + VmRSS: 256000, + RssAnon: 128000, + RssFile: 64000, + RssShmem: 64000, + VmData: 100000, + VmStk: 8192, + VmExe: 4096, + VmLib: 50000, + VmPTE: 1024, + VmPMD: 512, + VmSwap: 0, + HugetlbPages: 0, + VoluntaryCtxtSwitches: 1000, + NonVoluntaryCtxtSwitches: 50, + UIDs: [4]uint64{1000, 1000, 1000, 1000}, + GIDs: [4]uint64{100, 100, 100, 100}, + CpusAllowedList: []uint64{0, 1, 2, 3}, + } + + result := convertProcStatus(src) + + require.NotNil(t, result) + assert.Equal(t, int32(42), result.Pid) + assert.Equal(t, "postgres", result.Name) + assert.Equal(t, int32(42), result.Tgid) + assert.Equal(t, []int64{42, 1}, result.NsPids) + assert.Equal(t, int64(2048000), result.VmPeak) + assert.Equal(t, int64(1024000), result.VmSize) + assert.Equal(t, int64(0), result.VmLck) + assert.Equal(t, int64(0), result.VmPin) + assert.Equal(t, int64(512000), result.VmHwm) + assert.Equal(t, int64(256000), result.VmRss) + assert.Equal(t, int64(128000), result.RssAnon) + assert.Equal(t, int64(64000), result.RssFile) + assert.Equal(t, int64(64000), result.RssShmem) + assert.Equal(t, int64(100000), result.VmData) + assert.Equal(t, int64(8192), result.VmStk) + assert.Equal(t, int64(4096), result.VmExe) + assert.Equal(t, int64(50000), result.VmLib) + assert.Equal(t, int64(1024), result.VmPte) + assert.Equal(t, int64(512), result.VmPmd) + assert.Equal(t, int64(0), result.VmSwap) + assert.Equal(t, int64(0), result.HugetlbPages) + assert.Equal(t, int64(1000), result.VoluntaryCtxtSwitches) + assert.Equal(t, int64(50), result.NonVoluntaryCtxtSwitches) + assert.Equal(t, []int64{1000, 1000, 1000, 1000}, result.Uids) + assert.Equal(t, []int64{100, 100, 100, 100}, result.Gids) + assert.Equal(t, []int64{0, 1, 2, 3}, result.CpusAllowedList) +} + +func TestConvertProcIO(t *testing.T) { + src := &procfs.ProcIO{ + RChar: 1000000, + WChar: 500000, + SyscR: 200, + SyscW: 100, + ReadBytes: 4096000, + WriteBytes: 2048000, + CancelledWriteBytes: 512, + } + + result := convertProcIO(src) + + require.NotNil(t, result) + assert.Equal(t, int64(1000000), result.Rchar) + assert.Equal(t, int64(500000), result.Wchar) + assert.Equal(t, int64(200), result.Syscr) + assert.Equal(t, int64(100), result.Syscw) + assert.Equal(t, int64(4096000), result.ReadBytes) + assert.Equal(t, int64(2048000), result.WriteBytes) + assert.Equal(t, int64(512), result.CancelledWriteBytes) +} + +func TestParseCmdLineSessionStatus(t *testing.T) { + tests := []struct { + name string + cmdline string + expected string + }{ + { + name: "idle session", + cmdline: "postgres: 5432, gpadmin postgres localhost(33326) con21 cmd237786 idle", + expected: "idle", + }, + { + name: "SELECT query", + cmdline: "postgres: 5432, monitor postgres localhost(22122) con38 cmd1006767 SELECT", + expected: "SELECT", + }, + { + name: "idle session with different user", + cmdline: "postgres: 5432, monitor postgres localhost(31260) con3185445 cmd2631 idle", + expected: "idle", + }, + { + name: "idle session via unix socket", + cmdline: "postgres: 5432, gpadmin postgres [local] con3297072 cmd11 idle", + expected: "idle", + }, + { + name: "master logger process", + cmdline: "postgres: 5432, master logger process", + expected: "", + }, + { + name: "bgworker logerrors", + cmdline: "postgres: 5432, bgworker: logerrors", + expected: "", + }, + { + name: "checkpointer process", + cmdline: "postgres: 5432, checkpointer process", + expected: "", + }, + { + name: "writer process", + cmdline: "postgres: 5432, writer process", + expected: "", + }, + { + name: "wal writer process", + cmdline: "postgres: 5432, wal writer process", + expected: "", + }, + { + name: "archiver process", + cmdline: "postgres: 5432, archiver process last was 000000010000000F00000015", + expected: "", + }, + { + name: "stats collector process", + cmdline: "postgres: 5432, stats collector process", + expected: "", + }, + { + name: "bgworker dtx recovery", + cmdline: "postgres: 5432, bgworker: dtx recovery process", + expected: "", + }, + { + name: "bgworker ftsprobe", + cmdline: "postgres: 5432, bgworker: ftsprobe process", + expected: "", + }, + { + name: "bgworker gp_relsizes_stats_worker", + cmdline: "postgres: 5432, bgworker: gp_relsizes_stats_worker", + expected: "", + }, + { + name: "bgworker diskquota launcher", + cmdline: "postgres: 5432, bgworker: [diskquota] - launcher", + expected: "", + }, + { + name: "bgworker ic proxy", + cmdline: "postgres: 5432, bgworker: ic proxy process", + expected: "", + }, + { + name: "bgworker global deadlock detector", + cmdline: "postgres: 5432, bgworker: global deadlock detector process", + expected: "", + }, + { + name: "wal sender process", + cmdline: "postgres: 5432, wal sender process gpadmin rc1b-srh6mco58rmiivfc.mdb.yandexcloud.net(24578) streaming F/58000F80", + expected: "", + }, + { + name: "empty string", + cmdline: "", + expected: "", + }, + { + name: "unrelated process", + cmdline: "/usr/bin/python3 /opt/script.py", + expected: "", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := ParseCmdLineSessionStatus(tt.cmdline) + assert.Equal(t, tt.expected, result) + }) + } +} + +func TestGetPidProcInfo_NonExistentPid(t *testing.T) { + // A very large PID is guaranteed not to exist. + info, err := GetPidProcInfo(4194305000000, 1, 100) + assert.ErrorIs(t, err, ErrProcessNotFound) + assert.Nil(t, info) +} + +func TestGetPidProcInfo_OutOfRangePid(t *testing.T) { + // Negative and zero PIDs cannot correspond to real processes; + // expect ErrProcessNotFound. + tests := []struct { + name string + pid int64 + }{ + {"negative", -1}, + {"zero", 0}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + info, err := GetPidProcInfo(tt.pid, 1, 100) + assert.ErrorIs(t, err, ErrProcessNotFound) + assert.Nil(t, info) + }) + } +}