...

Source file src/google.golang.org/grpc/channelz/internal/protoconv/channel.go

Documentation: google.golang.org/grpc/channelz/internal/protoconv

     1  /*
     2   *
     3   * Copyright 2024 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 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  // GetTopChannels returns the protobuf representation of the channels starting
   118  // at startID (max of len), and returns end=true if no top channels exist with
   119  // higher IDs.
   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  // GetChannel returns the protobuf representation of the channel with the given
   129  // ID.
   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