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  }