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 channelz 20 21 import ( 22 "fmt" 23 "net" 24 "sync/atomic" 25 26 "google.golang.org/grpc/credentials" 27 ) 28 29 // SocketMetrics defines the struct that the implementor of Socket interface 30 // should return from ChannelzMetric(). 31 type SocketMetrics struct { 32 // The number of streams that have been started. 33 StreamsStarted atomic.Int64 34 // The number of streams that have ended successfully: 35 // On client side, receiving frame with eos bit set. 36 // On server side, sending frame with eos bit set. 37 StreamsSucceeded atomic.Int64 38 // The number of streams that have ended unsuccessfully: 39 // On client side, termination without receiving frame with eos bit set. 40 // On server side, termination without sending frame with eos bit set. 41 StreamsFailed atomic.Int64 42 // The number of messages successfully sent on this socket. 43 MessagesSent atomic.Int64 44 MessagesReceived atomic.Int64 45 // The number of keep alives sent. This is typically implemented with HTTP/2 46 // ping messages. 47 KeepAlivesSent atomic.Int64 48 // The last time a stream was created by this endpoint. Usually unset for 49 // servers. 50 LastLocalStreamCreatedTimestamp atomic.Int64 51 // The last time a stream was created by the remote endpoint. Usually unset 52 // for clients. 53 LastRemoteStreamCreatedTimestamp atomic.Int64 54 // The last time a message was sent by this endpoint. 55 LastMessageSentTimestamp atomic.Int64 56 // The last time a message was received by this endpoint. 57 LastMessageReceivedTimestamp atomic.Int64 58 } 59 60 // EphemeralSocketMetrics are metrics that change rapidly and are tracked 61 // outside of channelz. 62 type EphemeralSocketMetrics struct { 63 // The amount of window, granted to the local endpoint by the remote endpoint. 64 // This may be slightly out of date due to network latency. This does NOT 65 // include stream level or TCP level flow control info. 66 LocalFlowControlWindow int64 67 // The amount of window, granted to the remote endpoint by the local endpoint. 68 // This may be slightly out of date due to network latency. This does NOT 69 // include stream level or TCP level flow control info. 70 RemoteFlowControlWindow int64 71 } 72 73 type SocketType string 74 75 const ( 76 SocketTypeNormal = "NormalSocket" 77 SocketTypeListen = "ListenSocket" 78 ) 79 80 type Socket struct { 81 Entity 82 SocketType SocketType 83 ID int64 84 Parent Entity 85 cm *channelMap 86 SocketMetrics SocketMetrics 87 EphemeralMetrics func() *EphemeralSocketMetrics 88 89 RefName string 90 // The locally bound address. Immutable. 91 LocalAddr net.Addr 92 // The remote bound address. May be absent. Immutable. 93 RemoteAddr net.Addr 94 // Optional, represents the name of the remote endpoint, if different than 95 // the original target name. Immutable. 96 RemoteName string 97 // Immutable. 98 SocketOptions *SocketOptionData 99 // Immutable. 100 Security credentials.ChannelzSecurityValue 101 } 102 103 func (ls *Socket) String() string { 104 return fmt.Sprintf("%s %s #%d", ls.Parent, ls.SocketType, ls.ID) 105 } 106 107 func (ls *Socket) id() int64 { 108 return ls.ID 109 } 110 111 func (ls *Socket) addChild(id int64, e entry) { 112 logger.Errorf("cannot add a child (id = %d) of type %T to a listen socket", id, e) 113 } 114 115 func (ls *Socket) deleteChild(id int64) { 116 logger.Errorf("cannot delete a child (id = %d) from a listen socket", id) 117 } 118 119 func (ls *Socket) triggerDelete() { 120 ls.cm.deleteEntry(ls.ID) 121 ls.Parent.(entry).deleteChild(ls.ID) 122 } 123 124 func (ls *Socket) deleteSelfIfReady() { 125 logger.Errorf("cannot call deleteSelfIfReady on a listen socket") 126 } 127 128 func (ls *Socket) getParentID() int64 { 129 return ls.Parent.id() 130 } 131