Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc-cloned / deps / grpc / src / core / lib / channel / channelz.h
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 #ifndef GRPC_CORE_LIB_CHANNEL_CHANNELZ_H
20 #define GRPC_CORE_LIB_CHANNEL_CHANNELZ_H
21
22 #include <grpc/impl/codegen/port_platform.h>
23
24 #include <grpc/grpc.h>
25
26 #include "src/core/lib/channel/channel_trace.h"
27 #include "src/core/lib/gpr/time_precise.h"
28 #include "src/core/lib/gprpp/inlined_vector.h"
29 #include "src/core/lib/gprpp/manual_constructor.h"
30 #include "src/core/lib/gprpp/map.h"
31 #include "src/core/lib/gprpp/ref_counted.h"
32 #include "src/core/lib/gprpp/ref_counted_ptr.h"
33 #include "src/core/lib/gprpp/sync.h"
34 #include "src/core/lib/iomgr/error.h"
35 #include "src/core/lib/iomgr/exec_ctx.h"
36 #include "src/core/lib/json/json.h"
37
38 // Channel arg key for channelz node.
39 #define GRPC_ARG_CHANNELZ_CHANNEL_NODE "grpc.channelz_channel_node"
40
41 // Channel arg key to encode the channelz uuid of the channel's parent.
42 #define GRPC_ARG_CHANNELZ_PARENT_UUID "grpc.channelz_parent_uuid"
43
44 /** This is the default value for whether or not to enable channelz. If
45  * GRPC_ARG_ENABLE_CHANNELZ is set, it will override this default value. */
46 #define GRPC_ENABLE_CHANNELZ_DEFAULT true
47
48 /** This is the default value for the maximum amount of memory used by trace
49  * events per channel trace node. If
50  * GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE is set, it will override
51  * this default value. */
52 #define GRPC_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE_DEFAULT 1024 * 4
53
54 namespace grpc_core {
55
56 namespace channelz {
57
58 // Helpers for getting and setting GRPC_ARG_CHANNELZ_PARENT_UUID.
59 grpc_arg MakeParentUuidArg(intptr_t parent_uuid);
60 intptr_t GetParentUuidFromArgs(const grpc_channel_args& args);
61
62 class SocketNode;
63 class ListenSocketNode;
64
65 namespace testing {
66 class CallCountingHelperPeer;
67 class ChannelNodePeer;
68 }  // namespace testing
69
70 // base class for all channelz entities
71 class BaseNode : public RefCounted<BaseNode> {
72  public:
73   // There are only four high level channelz entities. However, to support
74   // GetTopChannelsRequest, we split the Channel entity into two different
75   // types. All children of BaseNode must be one of these types.
76   enum class EntityType {
77     kTopLevelChannel,
78     kInternalChannel,
79     kSubchannel,
80     kServer,
81     kSocket,
82   };
83
84  protected:
85   BaseNode(EntityType type, UniquePtr<char> name);
86
87  public:
88   virtual ~BaseNode();
89
90   // All children must implement this function.
91   virtual grpc_json* RenderJson() GRPC_ABSTRACT;
92
93   // Renders the json and returns allocated string that must be freed by the
94   // caller.
95   char* RenderJsonString();
96
97   EntityType type() const { return type_; }
98   intptr_t uuid() const { return uuid_; }
99   const char* name() const { return name_.get(); }
100
101  private:
102   // to allow the ChannelzRegistry to set uuid_ under its lock.
103   friend class ChannelzRegistry;
104   const EntityType type_;
105   intptr_t uuid_;
106   UniquePtr<char> name_;
107 };
108
109 // This class is a helper class for channelz entities that deal with Channels,
110 // Subchannels, and Servers, since those have similar proto definitions.
111 // This class has the ability to:
112 //   - track calls_{started,succeeded,failed}
113 //   - track last_call_started_timestamp
114 //   - perform rendering of the above items
115 class CallCountingHelper {
116  public:
117   CallCountingHelper();
118
119   void RecordCallStarted();
120   void RecordCallFailed();
121   void RecordCallSucceeded();
122
123   // Common rendering of the call count data and last_call_started_timestamp.
124   void PopulateCallCounts(grpc_json* json);
125
126  private:
127   // testing peer friend.
128   friend class testing::CallCountingHelperPeer;
129
130   // TODO(soheil): add a proper PerCPU helper and use it here.
131   struct AtomicCounterData {
132     // Define the ctors so that we can use this structure in InlinedVector.
133     AtomicCounterData() = default;
134     AtomicCounterData(const AtomicCounterData& that)
135         : calls_started(that.calls_started.Load(MemoryOrder::RELAXED)),
136           calls_succeeded(that.calls_succeeded.Load(MemoryOrder::RELAXED)),
137           calls_failed(that.calls_failed.Load(MemoryOrder::RELAXED)),
138           last_call_started_cycle(
139               that.last_call_started_cycle.Load(MemoryOrder::RELAXED)) {}
140
141     Atomic<intptr_t> calls_started{0};
142     Atomic<intptr_t> calls_succeeded{0};
143     Atomic<intptr_t> calls_failed{0};
144     Atomic<gpr_cycle_counter> last_call_started_cycle{0};
145     // Make sure the size is exactly one cache line.
146     uint8_t padding[GPR_CACHELINE_SIZE - 3 * sizeof(Atomic<intptr_t>) -
147                     sizeof(Atomic<gpr_cycle_counter>)];
148   } GPR_ALIGN_STRUCT(GPR_CACHELINE_SIZE);
149
150   struct CounterData {
151     intptr_t calls_started = 0;
152     intptr_t calls_succeeded = 0;
153     intptr_t calls_failed = 0;
154     gpr_cycle_counter last_call_started_cycle = 0;
155   };
156
157   // collects the sharded data into one CounterData struct.
158   void CollectData(CounterData* out);
159
160   // Really zero-sized, but 0-sized arrays are illegal on MSVC.
161   InlinedVector<AtomicCounterData, 1> per_cpu_counter_data_storage_;
162   size_t num_cores_ = 0;
163 };
164
165 // Handles channelz bookkeeping for channels
166 class ChannelNode : public BaseNode {
167  public:
168   ChannelNode(UniquePtr<char> target, size_t channel_tracer_max_nodes,
169               intptr_t parent_uuid);
170
171   // Returns the string description of the given connectivity state.
172   static const char* GetChannelConnectivityStateChangeString(
173       grpc_connectivity_state state);
174
175   intptr_t parent_uuid() const { return parent_uuid_; }
176
177   grpc_json* RenderJson() override;
178
179   // proxy methods to composed classes.
180   void AddTraceEvent(ChannelTrace::Severity severity, const grpc_slice& data) {
181     trace_.AddTraceEvent(severity, data);
182   }
183   void AddTraceEventWithReference(ChannelTrace::Severity severity,
184                                   const grpc_slice& data,
185                                   RefCountedPtr<BaseNode> referenced_channel) {
186     trace_.AddTraceEventWithReference(severity, data,
187                                       std::move(referenced_channel));
188   }
189   void RecordCallStarted() { call_counter_.RecordCallStarted(); }
190   void RecordCallFailed() { call_counter_.RecordCallFailed(); }
191   void RecordCallSucceeded() { call_counter_.RecordCallSucceeded(); }
192
193   void SetConnectivityState(grpc_connectivity_state state);
194
195   // TODO(roth): take in a RefCountedPtr to the child channel so we can retrieve
196   // the human-readable name.
197   void AddChildChannel(intptr_t child_uuid);
198   void RemoveChildChannel(intptr_t child_uuid);
199
200   // TODO(roth): take in a RefCountedPtr to the child subchannel so we can
201   // retrieve the human-readable name.
202   void AddChildSubchannel(intptr_t child_uuid);
203   void RemoveChildSubchannel(intptr_t child_uuid);
204
205  private:
206   void PopulateChildRefs(grpc_json* json);
207
208   // to allow the channel trace test to access trace_.
209   friend class testing::ChannelNodePeer;
210
211   UniquePtr<char> target_;
212   CallCountingHelper call_counter_;
213   ChannelTrace trace_;
214   const intptr_t parent_uuid_;
215
216   // Least significant bit indicates whether the value is set.  Remaining
217   // bits are a grpc_connectivity_state value.
218   Atomic<int> connectivity_state_{0};
219
220   Mutex child_mu_;  // Guards child maps below.
221   // TODO(roth): We don't actually use the values here, only the keys, so
222   // these should be sets instead of maps, but we don't currently have a set
223   // implementation.  Change this if/when we have one.
224   Map<intptr_t, bool> child_channels_;
225   Map<intptr_t, bool> child_subchannels_;
226 };
227
228 // Handles channelz bookkeeping for servers
229 class ServerNode : public BaseNode {
230  public:
231   ServerNode(grpc_server* server, size_t channel_tracer_max_nodes);
232
233   ~ServerNode() override;
234
235   grpc_json* RenderJson() override;
236
237   char* RenderServerSockets(intptr_t start_socket_id, intptr_t max_results);
238
239   void AddChildSocket(RefCountedPtr<SocketNode> node);
240
241   void RemoveChildSocket(intptr_t child_uuid);
242
243   void AddChildListenSocket(RefCountedPtr<ListenSocketNode> node);
244
245   void RemoveChildListenSocket(intptr_t child_uuid);
246
247   // proxy methods to composed classes.
248   void AddTraceEvent(ChannelTrace::Severity severity, const grpc_slice& data) {
249     trace_.AddTraceEvent(severity, data);
250   }
251   void AddTraceEventWithReference(ChannelTrace::Severity severity,
252                                   const grpc_slice& data,
253                                   RefCountedPtr<BaseNode> referenced_channel) {
254     trace_.AddTraceEventWithReference(severity, data,
255                                       std::move(referenced_channel));
256   }
257   void RecordCallStarted() { call_counter_.RecordCallStarted(); }
258   void RecordCallFailed() { call_counter_.RecordCallFailed(); }
259   void RecordCallSucceeded() { call_counter_.RecordCallSucceeded(); }
260
261  private:
262   CallCountingHelper call_counter_;
263   ChannelTrace trace_;
264   Mutex child_mu_;  // Guards child maps below.
265   Map<intptr_t, RefCountedPtr<SocketNode>> child_sockets_;
266   Map<intptr_t, RefCountedPtr<ListenSocketNode>> child_listen_sockets_;
267 };
268
269 // Handles channelz bookkeeping for sockets
270 class SocketNode : public BaseNode {
271  public:
272   SocketNode(UniquePtr<char> local, UniquePtr<char> remote,
273              UniquePtr<char> name);
274   ~SocketNode() override {}
275
276   grpc_json* RenderJson() override;
277
278   void RecordStreamStartedFromLocal();
279   void RecordStreamStartedFromRemote();
280   void RecordStreamSucceeded() {
281     gpr_atm_no_barrier_fetch_add(&streams_succeeded_, static_cast<gpr_atm>(1));
282   }
283   void RecordStreamFailed() {
284     gpr_atm_no_barrier_fetch_add(&streams_failed_, static_cast<gpr_atm>(1));
285   }
286   void RecordMessagesSent(uint32_t num_sent);
287   void RecordMessageReceived();
288   void RecordKeepaliveSent() {
289     gpr_atm_no_barrier_fetch_add(&keepalives_sent_, static_cast<gpr_atm>(1));
290   }
291
292   const char* remote() { return remote_.get(); }
293
294  private:
295   gpr_atm streams_started_ = 0;
296   gpr_atm streams_succeeded_ = 0;
297   gpr_atm streams_failed_ = 0;
298   gpr_atm messages_sent_ = 0;
299   gpr_atm messages_received_ = 0;
300   gpr_atm keepalives_sent_ = 0;
301   gpr_atm last_local_stream_created_cycle_ = 0;
302   gpr_atm last_remote_stream_created_cycle_ = 0;
303   gpr_atm last_message_sent_cycle_ = 0;
304   gpr_atm last_message_received_cycle_ = 0;
305   UniquePtr<char> local_;
306   UniquePtr<char> remote_;
307 };
308
309 // Handles channelz bookkeeping for listen sockets
310 class ListenSocketNode : public BaseNode {
311  public:
312   ListenSocketNode(UniquePtr<char> local_addr, UniquePtr<char> name);
313   ~ListenSocketNode() override {}
314
315   grpc_json* RenderJson() override;
316
317  private:
318   UniquePtr<char> local_addr_;
319 };
320
321 }  // namespace channelz
322 }  // namespace grpc_core
323
324 #endif /* GRPC_CORE_LIB_CHANNEL_CHANNELZ_H */