github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/grpc/channelz/service/service.go (about) 1 /* 2 * 3 * Copyright 2018 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 // Package service provides an implementation for channelz service server. 20 package service 21 22 import ( 23 "context" 24 "net" 25 26 "github.com/golang/protobuf/ptypes" 27 wrpb "github.com/golang/protobuf/ptypes/wrappers" 28 grpc "github.com/hxx258456/ccgo/grpc" 29 channelzgrpc "github.com/hxx258456/ccgo/grpc/channelz/grpc_channelz_v1" 30 channelzpb "github.com/hxx258456/ccgo/grpc/channelz/grpc_channelz_v1" 31 "github.com/hxx258456/ccgo/grpc/codes" 32 "github.com/hxx258456/ccgo/grpc/connectivity" 33 "github.com/hxx258456/ccgo/grpc/credentials" 34 "github.com/hxx258456/ccgo/grpc/grpclog" 35 "github.com/hxx258456/ccgo/grpc/internal/channelz" 36 "github.com/hxx258456/ccgo/grpc/status" 37 ) 38 39 func init() { 40 channelz.TurnOn() 41 } 42 43 var logger = grpclog.Component("channelz") 44 45 // RegisterChannelzServiceToServer registers the channelz service to the given server. 46 // 47 // Note: it is preferred to use the admin API 48 // (https://pkg.go.dev/google.golang.org/grpc/admin#Register) instead to 49 // register Channelz and other administrative services. 50 func RegisterChannelzServiceToServer(s grpc.ServiceRegistrar) { 51 channelzgrpc.RegisterChannelzServer(s, newCZServer()) 52 } 53 54 func newCZServer() channelzgrpc.ChannelzServer { 55 return &serverImpl{} 56 } 57 58 type serverImpl struct { 59 channelzgrpc.UnimplementedChannelzServer 60 } 61 62 func connectivityStateToProto(s connectivity.State) *channelzpb.ChannelConnectivityState { 63 switch s { 64 case connectivity.Idle: 65 return &channelzpb.ChannelConnectivityState{State: channelzpb.ChannelConnectivityState_IDLE} 66 case connectivity.Connecting: 67 return &channelzpb.ChannelConnectivityState{State: channelzpb.ChannelConnectivityState_CONNECTING} 68 case connectivity.Ready: 69 return &channelzpb.ChannelConnectivityState{State: channelzpb.ChannelConnectivityState_READY} 70 case connectivity.TransientFailure: 71 return &channelzpb.ChannelConnectivityState{State: channelzpb.ChannelConnectivityState_TRANSIENT_FAILURE} 72 case connectivity.Shutdown: 73 return &channelzpb.ChannelConnectivityState{State: channelzpb.ChannelConnectivityState_SHUTDOWN} 74 default: 75 return &channelzpb.ChannelConnectivityState{State: channelzpb.ChannelConnectivityState_UNKNOWN} 76 } 77 } 78 79 func channelTraceToProto(ct *channelz.ChannelTrace) *channelzpb.ChannelTrace { 80 pbt := &channelzpb.ChannelTrace{} 81 pbt.NumEventsLogged = ct.EventNum 82 if ts, err := ptypes.TimestampProto(ct.CreationTime); err == nil { 83 pbt.CreationTimestamp = ts 84 } 85 events := make([]*channelzpb.ChannelTraceEvent, 0, len(ct.Events)) 86 for _, e := range ct.Events { 87 cte := &channelzpb.ChannelTraceEvent{ 88 Description: e.Desc, 89 Severity: channelzpb.ChannelTraceEvent_Severity(e.Severity), 90 } 91 if ts, err := ptypes.TimestampProto(e.Timestamp); err == nil { 92 cte.Timestamp = ts 93 } 94 if e.RefID != 0 { 95 switch e.RefType { 96 case channelz.RefChannel: 97 cte.ChildRef = &channelzpb.ChannelTraceEvent_ChannelRef{ChannelRef: &channelzpb.ChannelRef{ChannelId: e.RefID, Name: e.RefName}} 98 case channelz.RefSubChannel: 99 cte.ChildRef = &channelzpb.ChannelTraceEvent_SubchannelRef{SubchannelRef: &channelzpb.SubchannelRef{SubchannelId: e.RefID, Name: e.RefName}} 100 } 101 } 102 events = append(events, cte) 103 } 104 pbt.Events = events 105 return pbt 106 } 107 108 func channelMetricToProto(cm *channelz.ChannelMetric) *channelzpb.Channel { 109 c := &channelzpb.Channel{} 110 c.Ref = &channelzpb.ChannelRef{ChannelId: cm.ID, Name: cm.RefName} 111 112 c.Data = &channelzpb.ChannelData{ 113 State: connectivityStateToProto(cm.ChannelData.State), 114 Target: cm.ChannelData.Target, 115 CallsStarted: cm.ChannelData.CallsStarted, 116 CallsSucceeded: cm.ChannelData.CallsSucceeded, 117 CallsFailed: cm.ChannelData.CallsFailed, 118 } 119 if ts, err := ptypes.TimestampProto(cm.ChannelData.LastCallStartedTimestamp); err == nil { 120 c.Data.LastCallStartedTimestamp = ts 121 } 122 nestedChans := make([]*channelzpb.ChannelRef, 0, len(cm.NestedChans)) 123 for id, ref := range cm.NestedChans { 124 nestedChans = append(nestedChans, &channelzpb.ChannelRef{ChannelId: id, Name: ref}) 125 } 126 c.ChannelRef = nestedChans 127 128 subChans := make([]*channelzpb.SubchannelRef, 0, len(cm.SubChans)) 129 for id, ref := range cm.SubChans { 130 subChans = append(subChans, &channelzpb.SubchannelRef{SubchannelId: id, Name: ref}) 131 } 132 c.SubchannelRef = subChans 133 134 sockets := make([]*channelzpb.SocketRef, 0, len(cm.Sockets)) 135 for id, ref := range cm.Sockets { 136 sockets = append(sockets, &channelzpb.SocketRef{SocketId: id, Name: ref}) 137 } 138 c.SocketRef = sockets 139 c.Data.Trace = channelTraceToProto(cm.Trace) 140 return c 141 } 142 143 func subChannelMetricToProto(cm *channelz.SubChannelMetric) *channelzpb.Subchannel { 144 sc := &channelzpb.Subchannel{} 145 sc.Ref = &channelzpb.SubchannelRef{SubchannelId: cm.ID, Name: cm.RefName} 146 147 sc.Data = &channelzpb.ChannelData{ 148 State: connectivityStateToProto(cm.ChannelData.State), 149 Target: cm.ChannelData.Target, 150 CallsStarted: cm.ChannelData.CallsStarted, 151 CallsSucceeded: cm.ChannelData.CallsSucceeded, 152 CallsFailed: cm.ChannelData.CallsFailed, 153 } 154 if ts, err := ptypes.TimestampProto(cm.ChannelData.LastCallStartedTimestamp); err == nil { 155 sc.Data.LastCallStartedTimestamp = ts 156 } 157 nestedChans := make([]*channelzpb.ChannelRef, 0, len(cm.NestedChans)) 158 for id, ref := range cm.NestedChans { 159 nestedChans = append(nestedChans, &channelzpb.ChannelRef{ChannelId: id, Name: ref}) 160 } 161 sc.ChannelRef = nestedChans 162 163 subChans := make([]*channelzpb.SubchannelRef, 0, len(cm.SubChans)) 164 for id, ref := range cm.SubChans { 165 subChans = append(subChans, &channelzpb.SubchannelRef{SubchannelId: id, Name: ref}) 166 } 167 sc.SubchannelRef = subChans 168 169 sockets := make([]*channelzpb.SocketRef, 0, len(cm.Sockets)) 170 for id, ref := range cm.Sockets { 171 sockets = append(sockets, &channelzpb.SocketRef{SocketId: id, Name: ref}) 172 } 173 sc.SocketRef = sockets 174 sc.Data.Trace = channelTraceToProto(cm.Trace) 175 return sc 176 } 177 178 func securityToProto(se credentials.ChannelzSecurityValue) *channelzpb.Security { 179 switch v := se.(type) { 180 case *credentials.TLSChannelzSecurityValue: 181 return &channelzpb.Security{Model: &channelzpb.Security_Tls_{Tls: &channelzpb.Security_Tls{ 182 CipherSuite: &channelzpb.Security_Tls_StandardName{StandardName: v.StandardName}, 183 LocalCertificate: v.LocalCertificate, 184 RemoteCertificate: v.RemoteCertificate, 185 }}} 186 case *credentials.OtherChannelzSecurityValue: 187 otherSecurity := &channelzpb.Security_OtherSecurity{ 188 Name: v.Name, 189 } 190 if anyval, err := ptypes.MarshalAny(v.Value); err == nil { 191 otherSecurity.Value = anyval 192 } 193 return &channelzpb.Security{Model: &channelzpb.Security_Other{Other: otherSecurity}} 194 } 195 return nil 196 } 197 198 func addrToProto(a net.Addr) *channelzpb.Address { 199 switch a.Network() { 200 case "udp": 201 // TODO: Address_OtherAddress{}. Need proto def for Value. 202 case "ip": 203 // Note zone info is discarded through the conversion. 204 return &channelzpb.Address{Address: &channelzpb.Address_TcpipAddress{TcpipAddress: &channelzpb.Address_TcpIpAddress{IpAddress: a.(*net.IPAddr).IP}}} 205 case "ip+net": 206 // Note mask info is discarded through the conversion. 207 return &channelzpb.Address{Address: &channelzpb.Address_TcpipAddress{TcpipAddress: &channelzpb.Address_TcpIpAddress{IpAddress: a.(*net.IPNet).IP}}} 208 case "tcp": 209 // Note zone info is discarded through the conversion. 210 return &channelzpb.Address{Address: &channelzpb.Address_TcpipAddress{TcpipAddress: &channelzpb.Address_TcpIpAddress{IpAddress: a.(*net.TCPAddr).IP, Port: int32(a.(*net.TCPAddr).Port)}}} 211 case "unix", "unixgram", "unixpacket": 212 return &channelzpb.Address{Address: &channelzpb.Address_UdsAddress_{UdsAddress: &channelzpb.Address_UdsAddress{Filename: a.String()}}} 213 default: 214 } 215 return &channelzpb.Address{} 216 } 217 218 func socketMetricToProto(sm *channelz.SocketMetric) *channelzpb.Socket { 219 s := &channelzpb.Socket{} 220 s.Ref = &channelzpb.SocketRef{SocketId: sm.ID, Name: sm.RefName} 221 222 s.Data = &channelzpb.SocketData{ 223 StreamsStarted: sm.SocketData.StreamsStarted, 224 StreamsSucceeded: sm.SocketData.StreamsSucceeded, 225 StreamsFailed: sm.SocketData.StreamsFailed, 226 MessagesSent: sm.SocketData.MessagesSent, 227 MessagesReceived: sm.SocketData.MessagesReceived, 228 KeepAlivesSent: sm.SocketData.KeepAlivesSent, 229 } 230 if ts, err := ptypes.TimestampProto(sm.SocketData.LastLocalStreamCreatedTimestamp); err == nil { 231 s.Data.LastLocalStreamCreatedTimestamp = ts 232 } 233 if ts, err := ptypes.TimestampProto(sm.SocketData.LastRemoteStreamCreatedTimestamp); err == nil { 234 s.Data.LastRemoteStreamCreatedTimestamp = ts 235 } 236 if ts, err := ptypes.TimestampProto(sm.SocketData.LastMessageSentTimestamp); err == nil { 237 s.Data.LastMessageSentTimestamp = ts 238 } 239 if ts, err := ptypes.TimestampProto(sm.SocketData.LastMessageReceivedTimestamp); err == nil { 240 s.Data.LastMessageReceivedTimestamp = ts 241 } 242 s.Data.LocalFlowControlWindow = &wrpb.Int64Value{Value: sm.SocketData.LocalFlowControlWindow} 243 s.Data.RemoteFlowControlWindow = &wrpb.Int64Value{Value: sm.SocketData.RemoteFlowControlWindow} 244 245 if sm.SocketData.SocketOptions != nil { 246 s.Data.Option = sockoptToProto(sm.SocketData.SocketOptions) 247 } 248 if sm.SocketData.Security != nil { 249 s.Security = securityToProto(sm.SocketData.Security) 250 } 251 252 if sm.SocketData.LocalAddr != nil { 253 s.Local = addrToProto(sm.SocketData.LocalAddr) 254 } 255 if sm.SocketData.RemoteAddr != nil { 256 s.Remote = addrToProto(sm.SocketData.RemoteAddr) 257 } 258 s.RemoteName = sm.SocketData.RemoteName 259 return s 260 } 261 262 func (s *serverImpl) GetTopChannels(ctx context.Context, req *channelzpb.GetTopChannelsRequest) (*channelzpb.GetTopChannelsResponse, error) { 263 metrics, end := channelz.GetTopChannels(req.GetStartChannelId(), req.GetMaxResults()) 264 resp := &channelzpb.GetTopChannelsResponse{} 265 for _, m := range metrics { 266 resp.Channel = append(resp.Channel, channelMetricToProto(m)) 267 } 268 resp.End = end 269 return resp, nil 270 } 271 272 func serverMetricToProto(sm *channelz.ServerMetric) *channelzpb.Server { 273 s := &channelzpb.Server{} 274 s.Ref = &channelzpb.ServerRef{ServerId: sm.ID, Name: sm.RefName} 275 276 s.Data = &channelzpb.ServerData{ 277 CallsStarted: sm.ServerData.CallsStarted, 278 CallsSucceeded: sm.ServerData.CallsSucceeded, 279 CallsFailed: sm.ServerData.CallsFailed, 280 } 281 282 if ts, err := ptypes.TimestampProto(sm.ServerData.LastCallStartedTimestamp); err == nil { 283 s.Data.LastCallStartedTimestamp = ts 284 } 285 sockets := make([]*channelzpb.SocketRef, 0, len(sm.ListenSockets)) 286 for id, ref := range sm.ListenSockets { 287 sockets = append(sockets, &channelzpb.SocketRef{SocketId: id, Name: ref}) 288 } 289 s.ListenSocket = sockets 290 return s 291 } 292 293 func (s *serverImpl) GetServers(ctx context.Context, req *channelzpb.GetServersRequest) (*channelzpb.GetServersResponse, error) { 294 metrics, end := channelz.GetServers(req.GetStartServerId(), req.GetMaxResults()) 295 resp := &channelzpb.GetServersResponse{} 296 for _, m := range metrics { 297 resp.Server = append(resp.Server, serverMetricToProto(m)) 298 } 299 resp.End = end 300 return resp, nil 301 } 302 303 func (s *serverImpl) GetServerSockets(ctx context.Context, req *channelzpb.GetServerSocketsRequest) (*channelzpb.GetServerSocketsResponse, error) { 304 metrics, end := channelz.GetServerSockets(req.GetServerId(), req.GetStartSocketId(), req.GetMaxResults()) 305 resp := &channelzpb.GetServerSocketsResponse{} 306 for _, m := range metrics { 307 resp.SocketRef = append(resp.SocketRef, &channelzpb.SocketRef{SocketId: m.ID, Name: m.RefName}) 308 } 309 resp.End = end 310 return resp, nil 311 } 312 313 func (s *serverImpl) GetChannel(ctx context.Context, req *channelzpb.GetChannelRequest) (*channelzpb.GetChannelResponse, error) { 314 var metric *channelz.ChannelMetric 315 if metric = channelz.GetChannel(req.GetChannelId()); metric == nil { 316 return nil, status.Errorf(codes.NotFound, "requested channel %d not found", req.GetChannelId()) 317 } 318 resp := &channelzpb.GetChannelResponse{Channel: channelMetricToProto(metric)} 319 return resp, nil 320 } 321 322 func (s *serverImpl) GetSubchannel(ctx context.Context, req *channelzpb.GetSubchannelRequest) (*channelzpb.GetSubchannelResponse, error) { 323 var metric *channelz.SubChannelMetric 324 if metric = channelz.GetSubChannel(req.GetSubchannelId()); metric == nil { 325 return nil, status.Errorf(codes.NotFound, "requested sub channel %d not found", req.GetSubchannelId()) 326 } 327 resp := &channelzpb.GetSubchannelResponse{Subchannel: subChannelMetricToProto(metric)} 328 return resp, nil 329 } 330 331 func (s *serverImpl) GetSocket(ctx context.Context, req *channelzpb.GetSocketRequest) (*channelzpb.GetSocketResponse, error) { 332 var metric *channelz.SocketMetric 333 if metric = channelz.GetSocket(req.GetSocketId()); metric == nil { 334 return nil, status.Errorf(codes.NotFound, "requested socket %d not found", req.GetSocketId()) 335 } 336 resp := &channelzpb.GetSocketResponse{Socket: socketMetricToProto(metric)} 337 return resp, nil 338 } 339 340 func (s *serverImpl) GetServer(ctx context.Context, req *channelzpb.GetServerRequest) (*channelzpb.GetServerResponse, error) { 341 var metric *channelz.ServerMetric 342 if metric = channelz.GetServer(req.GetServerId()); metric == nil { 343 return nil, status.Errorf(codes.NotFound, "requested server %d not found", req.GetServerId()) 344 } 345 resp := &channelzpb.GetServerResponse{Server: serverMetricToProto(metric)} 346 return resp, nil 347 }