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
19package channelz
20
21import (
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().
31type 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.
62type 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// SocketType represents the type of socket.
74type SocketType string
75
76// SocketType can be one of these.
77const (
78 SocketTypeNormal = "NormalSocket"
79 SocketTypeListen = "ListenSocket"
80)
81
82// Socket represents a socket within channelz which includes socket
83// metrics and data related to socket activity and provides methods
84// for managing and interacting with sockets.
85type Socket struct {
86 Entity
87 SocketType SocketType
88 ID int64
89 Parent Entity
90 cm *channelMap
91 SocketMetrics SocketMetrics
92 EphemeralMetrics func() *EphemeralSocketMetrics
93
94 RefName string
95 // The locally bound address. Immutable.
96 LocalAddr net.Addr
97 // The remote bound address. May be absent. Immutable.
98 RemoteAddr net.Addr
99 // Optional, represents the name of the remote endpoint, if different than
100 // the original target name. Immutable.
101 RemoteName string
102 // Immutable.
103 SocketOptions *SocketOptionData
104 // Immutable.
105 Security credentials.ChannelzSecurityValue
106}
107
108// String returns a string representation of the Socket, including its parent
109// entity, socket type, and ID.
110func (ls *Socket) String() string {
111 return fmt.Sprintf("%s %s #%d", ls.Parent, ls.SocketType, ls.ID)
112}
113
114func (ls *Socket) id() int64 {
115 return ls.ID
116}
117
118func (ls *Socket) addChild(id int64, e entry) {
119 logger.Errorf("cannot add a child (id = %d) of type %T to a listen socket", id, e)
120}
121
122func (ls *Socket) deleteChild(id int64) {
123 logger.Errorf("cannot delete a child (id = %d) from a listen socket", id)
124}
125
126func (ls *Socket) triggerDelete() {
127 ls.cm.deleteEntry(ls.ID)
128 ls.Parent.(entry).deleteChild(ls.ID)
129}
130
131func (ls *Socket) deleteSelfIfReady() {
132 logger.Errorf("cannot call deleteSelfIfReady on a listen socket")
133}
134
135func (ls *Socket) getParentID() int64 {
136 return ls.Parent.id()
137}