...
1
18
19 package protoconv
20
21 import (
22 "time"
23
24 "google.golang.org/grpc/codes"
25 "google.golang.org/grpc/connectivity"
26 "google.golang.org/grpc/internal/channelz"
27 "google.golang.org/grpc/status"
28 "google.golang.org/protobuf/types/known/timestamppb"
29
30 channelzpb "google.golang.org/grpc/channelz/grpc_channelz_v1"
31 )
32
33 func connectivityStateToProto(s *connectivity.State) *channelzpb.ChannelConnectivityState {
34 if s == nil {
35 return &channelzpb.ChannelConnectivityState{State: channelzpb.ChannelConnectivityState_UNKNOWN}
36 }
37 switch *s {
38 case connectivity.Idle:
39 return &channelzpb.ChannelConnectivityState{State: channelzpb.ChannelConnectivityState_IDLE}
40 case connectivity.Connecting:
41 return &channelzpb.ChannelConnectivityState{State: channelzpb.ChannelConnectivityState_CONNECTING}
42 case connectivity.Ready:
43 return &channelzpb.ChannelConnectivityState{State: channelzpb.ChannelConnectivityState_READY}
44 case connectivity.TransientFailure:
45 return &channelzpb.ChannelConnectivityState{State: channelzpb.ChannelConnectivityState_TRANSIENT_FAILURE}
46 case connectivity.Shutdown:
47 return &channelzpb.ChannelConnectivityState{State: channelzpb.ChannelConnectivityState_SHUTDOWN}
48 default:
49 return &channelzpb.ChannelConnectivityState{State: channelzpb.ChannelConnectivityState_UNKNOWN}
50 }
51 }
52
53 func channelTraceToProto(ct *channelz.ChannelTrace) *channelzpb.ChannelTrace {
54 pbt := &channelzpb.ChannelTrace{}
55 if ct == nil {
56 return pbt
57 }
58 pbt.NumEventsLogged = ct.EventNum
59 if ts := timestamppb.New(ct.CreationTime); ts.IsValid() {
60 pbt.CreationTimestamp = ts
61 }
62 events := make([]*channelzpb.ChannelTraceEvent, 0, len(ct.Events))
63 for _, e := range ct.Events {
64 cte := &channelzpb.ChannelTraceEvent{
65 Description: e.Desc,
66 Severity: channelzpb.ChannelTraceEvent_Severity(e.Severity),
67 }
68 if ts := timestamppb.New(e.Timestamp); ts.IsValid() {
69 cte.Timestamp = ts
70 }
71 if e.RefID != 0 {
72 switch e.RefType {
73 case channelz.RefChannel:
74 cte.ChildRef = &channelzpb.ChannelTraceEvent_ChannelRef{ChannelRef: &channelzpb.ChannelRef{ChannelId: e.RefID, Name: e.RefName}}
75 case channelz.RefSubChannel:
76 cte.ChildRef = &channelzpb.ChannelTraceEvent_SubchannelRef{SubchannelRef: &channelzpb.SubchannelRef{SubchannelId: e.RefID, Name: e.RefName}}
77 }
78 }
79 events = append(events, cte)
80 }
81 pbt.Events = events
82 return pbt
83 }
84
85 func channelToProto(cm *channelz.Channel) *channelzpb.Channel {
86 c := &channelzpb.Channel{}
87 c.Ref = &channelzpb.ChannelRef{ChannelId: cm.ID, Name: cm.RefName}
88
89 c.Data = &channelzpb.ChannelData{
90 State: connectivityStateToProto(cm.ChannelMetrics.State.Load()),
91 Target: strFromPointer(cm.ChannelMetrics.Target.Load()),
92 CallsStarted: cm.ChannelMetrics.CallsStarted.Load(),
93 CallsSucceeded: cm.ChannelMetrics.CallsSucceeded.Load(),
94 CallsFailed: cm.ChannelMetrics.CallsFailed.Load(),
95 }
96 if ts := timestamppb.New(time.Unix(0, cm.ChannelMetrics.LastCallStartedTimestamp.Load())); ts.IsValid() {
97 c.Data.LastCallStartedTimestamp = ts
98 }
99 ncs := cm.NestedChans()
100 nestedChans := make([]*channelzpb.ChannelRef, 0, len(ncs))
101 for id, ref := range ncs {
102 nestedChans = append(nestedChans, &channelzpb.ChannelRef{ChannelId: id, Name: ref})
103 }
104 c.ChannelRef = nestedChans
105
106 scs := cm.SubChans()
107 subChans := make([]*channelzpb.SubchannelRef, 0, len(scs))
108 for id, ref := range scs {
109 subChans = append(subChans, &channelzpb.SubchannelRef{SubchannelId: id, Name: ref})
110 }
111 c.SubchannelRef = subChans
112
113 c.Data.Trace = channelTraceToProto(cm.Trace())
114 return c
115 }
116
117
118
119
120 func GetTopChannels(startID int64, len int) (channels []*channelzpb.Channel, end bool) {
121 chans, end := channelz.GetTopChannels(startID, len)
122 for _, ch := range chans {
123 channels = append(channels, channelToProto(ch))
124 }
125 return channels, end
126 }
127
128
129
130 func GetChannel(id int64) (*channelzpb.Channel, error) {
131 ch := channelz.GetChannel(id)
132 if ch == nil {
133 return nil, status.Errorf(codes.NotFound, "requested channel %d not found", id)
134 }
135 return channelToProto(ch), nil
136 }
137
View as plain text